在初始化变量之前调用父类构造函数
Are parent class constructors called before initializing variables?
父类构造函数是在初始化变量之前调用的,还是编译器会先初始化类的变量?
例如:
class parent {
int a;
public:
parent() : a(123) {};
};
class child : public parent {
int b;
public:
// question: is parent constructor done before init b?
child() : b(456), parent() {};
}
可以,在派生类成员和构造函数体执行之前初始化基类。
12.6.2初始化基和成员[class.base.init]
在非委托构造函数中,初始化在以下订单:
-首先,并且仅用于most的构造函数派生类(1.8)、虚基类按顺序初始化它们出现在有向对象的深度优先的从左到右遍历中基类的无环图,其中"从左到右"的顺序是基类在派生类中的外观base-specifier-list .
-然后,直接基类初始化按照它们出现在基指定符列表中的顺序声明(不管初始化式的顺序如何)
-然后是非静态的类中声明数据成员的顺序初始化类定义(同样不考虑mem-initializers)。
-最后,的复合语句构造函数体被执行。
是的,父类构造函数总是在派生类之前被调用。否则,派生类不能"修改"父类设置的内容。
作为一些建议,如果您不确定,通常可以自己测试一下:
#include <iostream>
using namespace std;
class parent {
protected:
int a;
public:
parent() : a(123) { cout << "in parent(): a == " << a << endl; };
};
class child : public parent {
int b;
public:
// question: is parent constructor done before init b?
child() : b(456), parent() { cout << "in child(): a == " << a << ", b == " << b << endl; };
};
int main() {
child c;
return 0;
}
打印
in parent(): a == 123
in child(): a == 123, b == 456
从基构造函数之前初始化成员重定向。可能吗?…对于一些不完全是重复的单元选择,有一个解决方案:
通过多重继承,值可以在基类之前初始化。
class parent {
int a;
public:
parent(int b) : a{123 + b} {};
};
class cousin {
protected:
cousin() : b {456} {}
int b;
};
class child : public cousin, public parent {
public:
child() : cousin(), parent(b) {};
};
现在可以初始化b并在parent中使用。
是的,对象的构造从父类开始,到子类,所以构造函数调用是按这个顺序进行的。在破坏的情况下,这正好相反。
认为派生类是对其基类的额外添加或扩展,添加所以它添加了一些东西(这个东西必须已经存在)。然后,另一个问题是成员的初始化。这里,您提供了默认构造函数
public:
parent() : a(123) {};
所以成员将默认初始化为123,即使你这样创建parent:
parent p;
如果没有默认构造函数用value
初始化对象class parent {
public:
int a;
};
比member中的默认值要高,这取决于,如果类是P.O.D,则int将默认初始化为0,但如果不是,也就是说,你提供了更多的成员,如string或vector
class parent {
public:
int a;
std::string s;
std::vector<int> v;
};
如果没有默认构造函数初始化,int将具有随机值。
可以绕过语言,在调用基类之前构造类成员。我是这样做的:
class C
{
};
class A
{
public:
A(C *ptr);
};
class B : public A
{
public:
B() : A(allocateC()) {}
private:
C *m_ptr;
C *allocateC() { m_ptr = new C; return m_ptr; }
};
我目前正在研究如何使用placement new将初始化的类成员存储到类对象内存中,而不是将它们放在堆上。
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 调用父类函数来比较父类和子类
- 如何从派生类实例调用父类重载函数
- 尝试在 C++ 中的子类中调用父类的受保护函数
- 当调用子类的析构函数时,是否也会调用父类的析构函数
- C++:如何从外部调用父类函数
- 从派生类调用父类的模板函数
- QThreadPool调用父类QRunnable的纯虚拟函数
- 传递对象的地址会导致调用父类构造函数
- 函数调用父类方法而不是子类方法
- 加载调用父类的 DLL 和子 dll
- 使用派生类调用父类的模板化函数重载
- C++继承:调用父类构造函数
- 为什么派生类对象在没有参数的情况下自动调用父类构造函数
- C++父类,调用子类中的方法,调用父类方法
- 如何调用父类类型列表的子类的方法?C++
- 委托和调用父类构造函数:如何做到这两点?
- 如何调用父类复制构造函数
- 从对象指针调用父类方法
- 调用父类的构造函数给出未定义