父类中的构造方法不会将值分配给私有变量

时间:2017-05-29 05:38:44

标签: c++ oop inheritance constructor initialization

这是我的代码,您也可以从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构造函数使用X参数调用int构造函数,并将c值设置为11,但输出为0。< / p>

2 个答案:

答案 0 :(得分:5)

您应该使用member initializer list

  

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

e.g。

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

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

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

对于构造函数体中的X(23);,您只需创建一个临时X,它与X的基础子对象Z无关。 };然后将使用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)
}

答案 1 :(得分:4)

您不会调用基类的构造函数

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

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

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

X(int b) :
  c(11)
{}

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

成员初始化列表语法几乎等同于简单整数是构造成员时所做的赋值。但要注意,首先默认构造更复杂的子对象,然后调用它们的赋值运算符。这可能会导致性能的显着(恶化)差异,只需在成员初始化列表中指定它们并构建一次。