感谢您阅读我的问题。
我正在对派生类的默认构造函数的行为进行测试。
例如,这是我的结构:
class Base1 {
public:
int a1;
int b1;
virtual void display() const {
cout << "Class Base1" << endl;
}
};
class Derived : public Base1{
public:
int c;
int d;
Derived() :Base1(){
}
};
如您所见,我没有显式定义 base1 类的构造函数,因此我预计
a1
和 a2
不会被初始化。
Base1 b1;
Derived d;
Base1& rb1=d;
cout<<b1.a1<<endl;
cout<<rb1.a1<<endl;
输出:
b1.a1 -> -858993460
rb1.a1 -> 0
我不知道为什么当我调用派生类的默认构造函数时,int成员a1会被初始化。
更重要的是,如果我更改派生类构造函数的委托方法:
class Derived : public Base1{
public:
using Base2::Base2; //use 'using' to generate the derived class constructor
using Base1::Base1;
int c;
int d;
};
我再次运行代码:
Base1 b1;
Derived d;
Base1& rb1=d;
cout<<b1.a1<<endl;
cout<<rb1.a1<<endl;
输出更改为:
b1.a1 -> -858993460
rb1.a1 -> -858993460
这种格式有什么特别之处吗
Derived() :Base1()
?
提前感谢您的评论!
某些类型在值初始化(即当涉及
()
或 {}
时)和默认初始化(未提供初始化器,并且既不使用 ()
也不使用 {}
时)会有不同的行为。
标量类型就像这样(整数、浮点、枚举、指针、指向成员的指针)。值初始化将它们归零,而默认初始化则使它们未初始化。
有些课程就是这样。当默认构造函数在第一个声明中隐式生成或显式
=default
时,这两种初始化方法之间的选择将传播到所有未初始化的成员。 (显然这里也允许继承默认构造函数,我不确定继承一个是否有任何效果。)
在您的第一个片段中,
Base1
符合此条件,因此:
Base1 x;
留下 a1
,b1
未初始化。Base1 x{};
归零a1
,b1
。Derived
与条件不匹配,并且它的基 Base1
由 Derived
构造函数 (: Base1()
) 进行值初始化,因此:
Derived x;
和 Derived x{}
相同,它们将 a1
、b1
归零并保留 c
、d
未初始化。在第二个片段中,
Derived
确实符合这个条件,所以:
Derived x;
使所有成员未初始化。Derived x{}
将所有成员归零。