编译错误,因为构造函数必须显式初始化成员。

5
我有一个类CFirstCSecond。 我不能对第二个类做任何事情,但我可以对第一个类做一些事情。 我试图在第一个类中从第二个类创建对象,但编译器仍然不满意。
到目前为止,最好的解决方案是这样的:
class CFirst{
    public:
    CSecond m_sec;
    CFirst ( const CSecond & sec ) {
          CSecond m_sec(sec.a(),sec.b());
     };

class CSecond{
    public:
    CSecond ( int a, int b) : m_A ( a ), m_B ( b ){ }
    int a  ( void ) const { return m_A;  }
    int b ( void ) const { return m_B; }
    private:
    int m_A;
    int m_B;
};

但编译器报错:

'CFirst'的构造函数必须显式初始化成员变量'm_sec',该变量没有默认构造函数。

你有什么建议吗?

编辑:

我也尝试过(但没有成功)

 m_sec(sec.a(),sec.b());

代替
 CSecond m_sec(sec.a(),sec.b());

解释在答案下方的注释中。


3
初始化成员的正确语法是你在 CSecond 中对 m_Am_B 使用的那种语法。 - Matteo Italia
1
此外,在CFirst::CFirst(const CSecond&)中引用CSecond之前,您需要先声明它,因此您的类定义在这里是无序的。 - Davislor
1个回答

11
CFirst的构造函数中,CSecond m_sec(sec.a(),sec.b());并没有初始化成员变量m_sec,而是定义了一个名为m_sec的局部对象,这与成员变量m_sec无关。(它还隐藏了成员变量m_sec。)
你应该使用成员初始化列表来代替,例如:
CFirst ( const CSecond & sec ) : m_sec(sec.a(), sec.b()) {} // initialize data member m_sec via CSecond::CSecond(int, int) 
或者
CFirst ( const CSecond & sec ) : m_sec(sec) {} // initialize data member m_sec via CSecond's copy constructor 

额外说明

非静态数据成员只能通过成员初始化列表或者默认初始化列表(自 C++11 起)进行初始化。你不能在构造函数体内部对其进行初始化。所以CSecond m_sec(sec.a(),sec.b());会定义一个新的局部变量,而m_sec = sec;则是一条赋值语句;在这个赋值操作之前,m_sec 会试图被默认初始化。但是 CSecond 没有默认构造函数,这就导致了编译错误。


太棒了,谢谢。结果和预期一样。你能否详细描述一下,为什么我使用的解决方案不好?我还是不完全理解... - Smeagol
@Davislor,为什么使用“m_sec(sec.a(),sec.b());”而不是“CSecond m_sec(sec.a(),sec.b());”也不起作用呢? - Smeagol
2
@TGar 我添加了一些额外的解释。 - songyuanyao
1
啊,我之前说你可以在CFirst::CFirst()里面赋值是错的;还需要一个默认构造函数CSecond::CSecond()。如果你真的想要一个,你可以添加CSecond() : m_A(0), m_B(0) {}——但要小心;那会隐藏这里的错误,你会想知道为什么所有的CFirst对象都被初始化为零! - Davislor
哦,我明白了。谢谢你们两个。(@Davislor因为没有自动提醒) - Smeagol
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接