C++ 为什么成员变量在c++;构造函数初始化列表?

C++ 为什么成员变量在c++;构造函数初始化列表?,c++,initializer-list,C++,Initializer List,我遇到这个问题是因为我的代码中有一个bug,我很好奇为什么允许这样做。有什么原因允许对象成员在构造函数初始化列表中可见 #include <stdio.h> class derived { private: int * value2; public: derived(); }; derived::derived() : value2(value2){} // Uninitialized self-assignment int main() { de

我遇到这个问题是因为我的代码中有一个bug,我很好奇为什么允许这样做。有什么原因允许对象成员在构造函数初始化列表中可见

#include <stdio.h>

class derived {
  private:
    int * value2;
  public:
    derived();
};

derived::derived()
 : value2(value2){} // Uninitialized self-assignment

int main()
{
  derived thisChild;
}
#包括
类派生{
私人:
int*value2;
公众:
派生();
};
派生::派生()
:value2(value2){}//未初始化的自赋值
int main()
{
这个孩子;
}

Clang对此给出了警告,但遗憾的是g++没有。您可以将初始化列表视为方法体(特别是构造函数)的一部分,因此您可以在其方法中访问对象的成员变量是很自然的


此外,您可能希望重用已创建的成员变量来初始化其他成员变量--注意:您必须知道初始化的确切顺序(成员变量声明的顺序),以确保可移植地使用此变量。如果此变量不可见,则无法写入:

A(int n) : some_num(n), another_num(some_num*10) {}
那么成员初始化列表有什么意义呢

#include <stdio.h>

class derived {
  private:
    int * value2;
  public:
    derived();
};

derived::derived()
 : value2(value2){} // Uninitialized self-assignment

int main()
{
  derived thisChild;
}
对于自初始化(未初始化变量),您甚至可以执行以下操作:

int xyz = xyz; //will compile

因此,您可以使用另一个成员初始化一个成员;如果另一个已经初始化,或者您只是使用它的地址初始化指针或引用,这是非常好的。例如:

struct Thingy
{
    int & r;
    int a;
    int b;

    Thingy(int x) :
        r(a),   // OK - a has a valid address, and we're not using the value
        a(x),
        b(a)    // OK - a has been initialised
    {}
};

允许这一点而不允许您的示例是相当棘手的。

我想您的意思是为什么在初始值设定项表达式中可以访问成员变量

一个原因是一个成员变量的初始化可能依赖于另一个成员变量


这是很脆弱的,但有时为了避免诸如人工基类之类的笨拙代码,这是必需的。

问题是关于用成员初始化成员,而不是用参数初始化成员。@MarkRansom,请重新阅读答案。Nawaz示例中的第二个初始化器使用第一个初始化数据成员的值,OP明确询问为什么成员在初始化列表中可见。@HristoIliev,自从我留下评论后,答案已修改。最初,构造函数示例只是
A(intn):some_num(n){}
@HristoIliev:Mark是正确的。当我在回答中添加更多内容时,他已经发布了评论。因此,最初
另一个\u num(some\u num*10)
部分不在那里,我正在添加此部分。已确认竞争条件:)如果使用4.7和
-Winit self,G++会发出警告