指向成员对象的成员指针和声明顺序

Posted

技术标签:

【中文标题】指向成员对象的成员指针和声明顺序【英文标题】: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 和赋值运算符都不会对此有所帮助。它只适用于指针(或引用) 【参考方案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”,我看不出任何问题

以上是关于指向成员对象的成员指针和声明顺序的主要内容,如果未能解决你的问题,请参考以下文章

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合

在类声明中处理指向成员函数的指针

c++对象模型

如何声明一个作为类成员的函数并返回指向线程的函数指针?

其实C语言就是三种结构吧?顺序结构、选择结构、循环结构?

C++指向对象成员的指针