【问题标题】:Compiler error because constructor must explicitly initialize the member编译器错误,因为构造函数必须显式初始化成员
【发布时间】:2017-09-04 11:40:32
【问题描述】:

我有课程CFirst 和CSecond。 第二节课我什么都做不了,但第一节课我可以做点什么。
我正在尝试从第一个中的第二个创建一个对象,但编译器仍然不满意。

目前最好的是:

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());

解释在答案下面的cmets中。

【问题讨论】:

  • 初始化成员的正确语法是您在CSecond 中为m_A 和m_B 使用的语法。
  • 另外,你需要先声明CSecond,然后才能在CFirst::CFirst(const CSecond&)中引用它,所以你的类定义在这里是乱序的。

标签: c++ class c++11 constructor compiler-errors


【解决方案1】:

在CFirst的构造函数内部,CSecond m_sec(sec.a(),sec.b());并没有初始化成员m_sec,而是定义了一个名为m_sec的本地对象,与成员m_sec无关。 (并且它隐藏了成员m_sec。)

您应该改用member intializer list,例如

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 

补充说明

Non-static data members 只能由成员初始化器列表或默认初始化器列表初始化(C++11 起)。您只是不能在构造函数的主体内执行此操作。所以CSecond m_sec(sec.a(),sec.b());会定义一个新的局部变量,m_sec = sec;是一个赋值;在分配 m_sec 之前,将很容易被默认初始化。但是CSecond没有默认构造函数,导致编译错误。

【讨论】:

  • 非常感谢。按预期工作。您能否描述更多,为什么我使用的解决方案不好?还是没完全看懂……
  • @TGar 我在第一段里解释过了,你不明白哪一部分?
  • 不是初始化this->m_sec,而是创建一个单独的局部变量,其名称与隐藏类成员的名称相同。
  • @TGar 我添加了一些额外的解释。
  • 啊,我说你可以在CFirst::CFirst()里面赋值时我弄错了;仍然需要一个默认构造函数CSecond::CSecond()。如果你真的想要一个,你可以添加CSecond() : m_A(0), m_B(0) {}——但要小心;那会在这里隐藏错误,您会想知道为什么所有CFirst 对象都被初始化为零!
猜你喜欢
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多