在构造对象之前使用对象成员

时间:2014-03-27 08:45:10

标签: c++ crtp static-polymorphism

我有以下简单的代码:

#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上测试了它)

1 个答案:

答案 0 :(得分:0)

它会在这个特定情况下起作用,但我建议不要这样做。 代码中的细微变化可能会突然破坏逻辑(例如,某人将方法设置为虚拟,有人在构造函数中初始化数据成员a或派生,...)。

如果基类需要派生类的信息,那么派生类必须将该信息传递给基类的构造函数。在这个类中,值37应该从Derived的构造函数传递给Base的构造函数。

当必须初始化数据成员a时,在Derived的构造函数中初始化它,而不是在其他地方。

编辑:在C ++ 11中,如果Derived类想要在Base的构造函数中注入代码,它可以将lambda传递给Base。 Base然后只在其构造函数中执行lambda。