我有以下简单的代码:
#include <iostream>
#include <vector>
template <class Derived>
struct Base
{
Base()
{
static_cast<Derived*>(this)->foo();
}
std::vector<int> m_ints;
};
struct Derived : Base<Derived>
{
Derived() : Base()
{
std::cout << a;
}
void foo()
{
m_ints.push_back(37);
a = 4;
}
int a;
};
int main()
{
Derived d;
return 0;
}
我知道在创建对象时调用构造函数的顺序。构造函数从&#34;大多数基础 - &gt;调用。向下&#34 ;.因此,在Base构造函数中,Derived对象未完全构造。
1)当Derived::foo
没有触摸Base
对象时,在Derived::foo
构造函数中调用Derived
是否安全?我的意思是,当没有a = 4
这样的行时,只需触摸Base
对象。
2)如果我运行已发布的代码,它确实有效,尽管我正在触摸当时不应存在的a
。是否可以保证工作? (我在VS2013,VS2010和GCC 4.8.1 on Ideone上测试了它)
答案 0 :(得分:0)
它会在这个特定情况下起作用,但我建议不要这样做。 代码中的细微变化可能会突然破坏逻辑(例如,某人将方法设置为虚拟,有人在构造函数中初始化数据成员a或派生,...)。
如果基类需要派生类的信息,那么派生类必须将该信息传递给基类的构造函数。在这个类中,值37应该从Derived的构造函数传递给Base的构造函数。
当必须初始化数据成员a时,在Derived的构造函数中初始化它,而不是在其他地方。
编辑:在C ++ 11中,如果Derived类想要在Base的构造函数中注入代码,它可以将lambda传递给Base。 Base然后只在其构造函数中执行lambda。