从派生 class 成员初始化基 class 引用
Initialization of a base class reference from a derived class member
我有两个 class,Base
和 Derived
。 Derived
使用自己的成员对象构造 Base
,该成员对象继承自 Base::BaseChild
.
struct Base
{
struct BaseChild
{
int x = 5;
};
Base(BaseChild& c): baseData(c), constantVar(c.x)
{
assert(constantVar == 5);
}
int getX() const {return baseData.x;}
private:
const int constantVar;
BaseChild& baseData;
};
struct Derived: public Base
{
struct DerivedChild: public BaseChild
{
double y = 4.0;
};
Derived(): Base(data) {}
private:
DerivedChild data;
};
Derived myObject;
assert(myObject.getX() == 5);
推理:我这样做是因为对于我的情况来说一切看起来都非常封装,我需要发送 Childs 来交换他们的内容(vector
,shared_ptr
, unique_ptr
) 与其他 Childs,保持子内存地址,我仍然可以从基 class 访问 Child 对象,而不需要虚函数,这会降低我的应用程序性能。
问题:我读过另一个 post like this one,其中说明 Derived
成员在 [=13] 之前初始化=] 不可能。所以 constantVar
断言总是会失败。但是 getX()
在构造函数之后工作正常,我对构造函数结束后调用的这些函数很感兴趣。这样安全吗?还是这里有什么隐患?
Derived
的基础 class Base
在成员 data
之前构造。
因此,当您将对它的引用传递给 Base
的构造函数时,data
将不会被初始化。初始化将在该构造函数调用之后发生。
然而,您正试图在 Base
的构造函数中读取 data
的成员 x
。此时 data
的生命周期尚未开始,在其生命周期之外访问对象的 non-static 数据成员的值会导致未定义的行为。
断言是否成功并不重要。未定义的行为允许任何一种结果。
如果您不尝试在 Base
的构造函数中访问 data
的值,而只是存储引用,情况可能会有所不同(尽管从技术上讲不是标准中的规则)
我有两个 class,Base
和 Derived
。 Derived
使用自己的成员对象构造 Base
,该成员对象继承自 Base::BaseChild
.
struct Base
{
struct BaseChild
{
int x = 5;
};
Base(BaseChild& c): baseData(c), constantVar(c.x)
{
assert(constantVar == 5);
}
int getX() const {return baseData.x;}
private:
const int constantVar;
BaseChild& baseData;
};
struct Derived: public Base
{
struct DerivedChild: public BaseChild
{
double y = 4.0;
};
Derived(): Base(data) {}
private:
DerivedChild data;
};
Derived myObject;
assert(myObject.getX() == 5);
推理:我这样做是因为对于我的情况来说一切看起来都非常封装,我需要发送 Childs 来交换他们的内容(vector
,shared_ptr
, unique_ptr
) 与其他 Childs,保持子内存地址,我仍然可以从基 class 访问 Child 对象,而不需要虚函数,这会降低我的应用程序性能。
问题:我读过另一个 post like this one,其中说明 Derived
成员在 [=13] 之前初始化=] 不可能。所以 constantVar
断言总是会失败。但是 getX()
在构造函数之后工作正常,我对构造函数结束后调用的这些函数很感兴趣。这样安全吗?还是这里有什么隐患?
Derived
的基础 class Base
在成员 data
之前构造。
因此,当您将对它的引用传递给 Base
的构造函数时,data
将不会被初始化。初始化将在该构造函数调用之后发生。
然而,您正试图在 Base
的构造函数中读取 data
的成员 x
。此时 data
的生命周期尚未开始,在其生命周期之外访问对象的 non-static 数据成员的值会导致未定义的行为。
断言是否成功并不重要。未定义的行为允许任何一种结果。
如果您不尝试在 Base
的构造函数中访问 data
的值,而只是存储引用,情况可能会有所不同(尽管从技术上讲不是标准中的规则)