当无法重新排序时,依赖成员初始化
Dependent member initialization, when reorder is not possible
#include <iostream>
class BarParent
{
public:
int x;
virtual void fuz() = 0;
};
class BarChild : public BarParent
{
public:
BarChild(int new_x){x = new_x;}
virtual void fuz(){}
};
class FooParent
{
public:
BarParent* p_barPar;
FooParent (BarChild* new_p_bar)
{
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
};
class FooChild: public FooParent
{
public:
BarChild barChild;
FooChild(int new_x):FooParent(&barChild), barChild(new_x){}
};
int main()
{
FooChild foo(60);
BarChild bar(99);
FooParent fooP(&bar);
}
输出:-548726160
99
我明白为什么我得到这个结果(未定义的行为),barChild
在初始化之前被使用。我的问题是什么是"正确的"做处理这个
这种情况下需要修复的是设计,而不是代码。
由你自己设计:
-
BarChild
必须先于FooParent
。 -
FooParent
必须在FooChild
之前构建。 -
FooChild
必须先于BarChild
。
当你想要FooParent
和FooChild
都引用同一个Bar对象时——就像你在代码中尝试的那样——设计父类来管理它。
一个示例解决方案:
FooParent (BarChild* new_p_bar)
{
if ( new_p_bar == NULL )
new_p_bar = new BarChild;
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
这里,FooChild
不需要它自己的这个对象的实例
尊重初始化的顺序。
可以在BarParent内部创建一个函数来设置指针p_barPar。在FooChild的构造函数中调用该函数。
是否有任何理由你不能使barChild(在FooChild)一个指针,以及?
我认为你将不得不找到另一个例子:这是错误的,因为RAIII原则没有强制执行:FooParent
持有一个指针上的值,它不控制。这个设置失败的一个有趣的例子是切片问题。
快速解决方案:
class FooChild: private BarChild, public FooParent
{
public:
FooChild(int new_x): BarChild(new_x), FooParent(this) {}
};
相关文章:
- 初始化依赖于子类的继承类的常量类成员
- 如何初始化依赖于先前条目的可变参数模板?
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 可以安全地依赖unordered_map中的初始化值(哈希映射)
- 使用依赖于 "this" C++ 的比较结构初始化集合
- 构造函数初始化列表中的循环依赖项
- 初始化依赖于另一个类成员的类成员
- 如何强制依赖静态对象(包括模板成员)的初始化顺序
- C++:使用RAII解析构造函数-初始化器列表依赖项
- 与可以一个从另一个初始化的类的循环依赖关系
- 如何在具有依赖元素类型的模板类构造函数中初始化向量
- 在c++中,当组合对象构造函数有依赖关系时,如何在初始化列表中强制它们的顺序
- 文件间依赖变量的初始化顺序是什么?
- 依赖于初始化的顺序
- 依赖初始化列表
- 在依赖的情况下静态初始化
- 如何初始化模板化类中依赖于T类型的静态const成员
- 为什么标准不允许在模板形参列表中初始化依赖于常量的类型
- 带逗号的相互依赖初始化
- 构造函数执行顺序/顺序:函数中静态变量(类实例)的依赖初始化