1

我有以下简单的代码:

#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;
}

我知道创建对象时调用构造函数的顺序。构造函数是从“最基础 -> 向下”调用的。所以在 Base 构造函数中,Derived 对象没有完全构造。

1)Derived::foo在没有触摸对象时调用Base构造函数是否安全?我的意思是,当没有这样的线时,只是触摸对象。Derived::fooDeriveda = 4Base

2)如果我运行发布的代码,它确实有效,尽管我正在触及a当时不应该存在的代码。能保证工作吗?(我在 Ideone 上的 VS2013、VS2010 和GCC 4.8.1 上对其进行了测试

4

1 回答 1

0

它适用于这种特定情况,但我建议不要这样做。代码中的细微更改可能会突然破坏逻辑(例如,有人将方法 foo 设为虚拟,有人在构造函数或 Derived 中初始化数据成员 a,...)。

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

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

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

于 2014-03-27T09:08:46.460 回答