【问题标题】:Constructor in the parent class doesn't assign the value to a private variable父类中的构造函数不会将值分配给私有变量
【发布时间】:2017-10-29 08:04:04
【问题描述】:

这是我的代码,你也可以从http://cpp.sh/5lsds运行它

#include "iostream"
using namespace std;
class X{
private:
    int c;
public:
    X(){}
    X(int b){
    c = 11;
    }
    int getC();
};
class Z:public X{
public:
    Z(int n){
        X(23);
    }
};
int main()
{
    Z z(1);
    cout<<z.getC()<<endl;
    return 0; 
}
int X::getC(){
    return c;
}

我需要有X(){} 行,因为子构造函数需要调用父默认构造函数。

如果你从http://cpp.sh/5lsds 运行程序,你会看到输出是0,而我希望它是11。由于Z 构造函数使用int 参数调用X 构造函数并将c 值设置为11,但输出为0

【问题讨论】:

  • X(23); 表示创建一个临时 X,然后立即将其销毁。与*this的X子部分无关
  • 如果你是从Java背景来的C++,你最好忘记这一切。

标签: c++ oop inheritance constructor initialization


【解决方案1】:

你应该使用member initializer list

在类的构造函数的定义中,成员初始化器列表指定直接和虚拟基子对象和非静态数据成员的初始化器。

例如

Z(int n) : X(23) {}

我需要有X(){} 行,因为子构造函数需要调用父默认构造函数。

使用成员初始化器列表不再需要它(在此代码示例中)。

对于构造函数体中的X(23);,你只是创建了一个临时的X,它与Z的基础子对象X无关;然后将使用X(即X::X())的默认构造函数。即它相当于:

Z(int n) : X() {  // initialize the base suboject X via X::X()
    X(23);        // create an unnamed temporary via X::X(int)
}

【讨论】:

    【解决方案2】:

    你不调用基类的构造函数

    Z(int n){
        X(23);
    }
    

    这会创建一个未命名的临时 X 对象,并将 23 传递给它的构造函数。它不构造 Z 的 X 子对象。

    在 C++ 中,我们使用成员初始化器列表语法构造基和成员:

    X(int b) :
      c(11)
    {}
    
    Z(int n) :
      X(23)
    {}
    

    成员初始值设定项列表语法几乎等同于当简单整数是构造成员时所做的赋值。但请注意,更复杂的子对象将首先被默认构造,然后调用它们的赋值运算符。仅在成员初始化器列表中指定它们并构造一次,这可能会在性能上产生实质性(恶化)差异。

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 2017-03-04
      • 2014-10-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2020-01-16
      • 2011-11-19
      • 1970-01-01
      相关资源
      最近更新 更多