可以将未初始化的对象传递给父类,如下例所示
class C
{
public:
C(int i):
m_i(i)
{};
int m_i;
}
class T
{
public:
T(C & c):
m_c(c)
{
};
C & m_c;
};
class ST : public T
{
public:
ST():
T(m_ci),
m_ci(999)
{
};
C m_ci;
};
在class T
构造函数中,c
是对未初始化对象的引用。如果class T
在构造期间使用c
对象,则可能会导致错误。但由于它不是,这编译并正常工作。我的问题是 - 它是否会制定某种范式或良好的设计指令?如果是这样,有什么选择,因为我发现在子类中分配父对象所需的对象很有用。
在旁注中,我想知道为什么不可能更改初始化顺序,以便在初始化某些成员之后调用基类构造函数。
答案 0 :(得分:3)
将引用或指针传递给未初始化的内容在技术上完全没问题。
但你问的原因可能是你认为容易出错的事情,通过一些调用链可能会在初始化之前无意中访问该对象。我认为这是一个有效的问题。还有一件事可能出错,即基类T
中的代码现在可能通过直接更改ST
实例的数据成员来使ST
的类不变量无效... < / p>
所以,我认为这有点风险。
关于初始化顺序,C ++基于在层次结构中从部分构建的思想。如果构造函数抛出,那么完全构造的东西会被自动破坏。对于更随意的施工顺序,这将更加困难或效率更低。
干杯&amp;第h。,
答案 1 :(得分:2)
我已经看过很多了,许多编译器都会发出警告。如果T
构造函数从不取消引用c
引用,那就没关系。
如果您不想要警告,则需要进行两阶段构建。在Init(C&)
中创建一个受保护的T
方法,然后在ST
构造函数体中调用它 - 遗憾的是m_c
需要指针来执行此操作(因为引用可以不能重新分配到另一个对象)
答案 2 :(得分:1)
您可以,但您会得到未定义的行为。
在Boost的实用程序中,您会找到由base-from-member idiom创建的R. Samuel Klatchko。基本上,你在私人会员的位置建立私人基地。此基础首先被初始化,您可以将其用于其他基础:
// ...
class C_base
{
public:
C_base(int i) :
m_ci(i)
{}
C m_ci;
};
class ST :
private C_base
public T
{
public:
ST() :
C_base(999),
T(m_ci),
{
};
};
Boost的实用程序消除了重复的代码。