【问题标题】:Member pointer to member object and declaration order指向成员对象的成员指针和声明顺序
【发布时间】:2013-03-13 12:01:11
【问题描述】:
#include <iostream>

class FooParent
{
    public:
        FooParent(int* new_p_bar)
        {
            p_bar = new_p_bar;
        }
    public:
        int* p_bar;
};

class FooChild : public FooParent
{
    public:
        int bar;
    public:
        FooChild(int new_x)
        :FooParent(&bar)
        ,bar(new_x) \\ point of concern
            {} 
};

int main()
{ 
    FooChild foo(8);
    std::cout << foo.bar << std::endl;

}

上面的示例按我的意愿工作。即将指针p_bar 链接到bar。但是,我担心的是我指向的成员的构造函数尚未调用。

此代码是否有效,或者标准对此有什么要说的。如果不是,还有什么办法。

注意:在我的应用程序中bar 是一个对象Bar(不是int),这有什么影响吗?

【问题讨论】:

  • 构造函数将被调用。初始化列表中的顺序与构造顺序不同。成员变量按照在类中的声明顺序进行初始化。
  • 如果FooParent的c-tor只存储了Bar的地址,而FooParent(&amp;bar)bar(new_x)之间没有其他初始化,那么看来这里没有问题
  • 换句话说,它只适用于指针(或引用)。不是对象的副本
  • @borisbn 所以如果我想使用它,我将不得不实现复制构造函数(和复制赋值运算符)来考虑这一点。对吗?
  • 不。复制 c-tor 和赋值运算符都不会对此有所帮助。它只适用于指针(或引用)

标签: c++ pointers inheritance member


【解决方案1】:

如果您将指针传递给成员,则没有未定义的行为,直到您尝试取消引用它。如果您想调用构造函数,请查看base-from-member idiom http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member

【讨论】:

    【解决方案2】:

    看看这个:

    class FooParent {
        public:
            FooParent(int* new_p_bar)
            {
                p_bar = new_p_bar;
                *p_bar = 99; // this has no sense
            }
            void set99() {
                *p_bar = 99; // this - has
            }
        public:
            int* p_bar;
    };
    
    class FooChild : public FooParent
    {
        public:
            int bar;
        public:
            FooChild(int new_x)
            :FooParent(&bar)
            ,bar(new_x) // point of concern
                {} 
    };
    
    int main()
    { 
        FooChild foo( 42 );
        std::cout << foo.bar << std::endl;
        foo.set99();
        std::cout << foo.bar << std::endl;
    }
    

    LWS.

    我的意思是,如果FooParent 的构造函数只存储一个指针 指向外部int(或Bar - 没关系)那么就不会有问题。

    另一方面,如果您将bar副本 提供给FooParent - 就像这样

    class FooParent
    {
        public:
            FooParent(Bar new_p_bar)
            {
                p_bar = new_p_bar;
            }
            void set99() {
                p_bar = 99; // this - has
            }
        public:
            Bar p_bar;
    };
    
    class FooChild : public FooParent
    {
        public:
            Bar bar;
        public:
            FooChild(Bar new_x)
            :FooParent(bar)
            ,bar(new_x) // point of concern
                {} 
    };
    
    int main()
    { 
        FooChild foo( 42 );
        std::cout << foo.bar << std::endl;
        foo.set99();
        std::cout << foo.bar << std::endl;
    }
    

    LWS.

    这行不通。即使Bar 会有一个复制 c-tor 或/和赋值运算符

    【讨论】:

    • 我说的是复制 c-tor 并为 FooChild 复制分配,这样当它复制 FooChild 时,它会将 p_bar 分配给新复制的 Bar。这样就够了吗?
    • 哦...对不起。我想到了 Bar 的副本 c-tor ... 如果“它将 p_bar 分配给新复制的 Bar”,我看不出任何问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2013-05-02
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    相关资源
    最近更新 更多