【问题标题】:Using object members before object is constructed在构造对象之前使用对象成员
【发布时间】:2014-03-27 08:45:10
【问题描述】:

我有以下简单代码:

#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 不接触Derived 对象时,在Base 构造函数中调用Derived::foo 是否安全?我的意思是,当没有a = 4 这样的行时,只需触摸Base 对象。

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

【问题讨论】:

  • 你想做什么?
  • 看看this

标签: c++ crtp static-polymorphism


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢您的回答。您能否提供更多信息,如何从 Derive do Base 传递 lambda 以便能够在 Base 构造函数中调用 lambda?在实际情况下,Derive 有几个构造函数,我不想在每个构造函数中都传递 lambda。还有其他方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多