c++ - 使用派生类成员进行父类的初始化

标签 c++ initialization derived-class initializer-list

我想初始化一个从类A派生的类B,并且在B中我首先构造一个使用的缓存构造A,例如,

class B: public A {

public:
  B(): A(cache_), cache_(this->buildCache_())

protected:
  const SomeDataType cache_;

private:
  SomeDataType
  buildCache_() const
  {
    // expensive cache construction
  }

}

不会起作用,因为父对象A总是首先初始化(在cache_填充之前)。

(为了完整起见:cache_ 在从 B 派生的类中多次使用。)

作为替代方案,我可以这样做

class B: public A {

public:
  B(): A(this->buildCache_())

protected:
  const SomeDataType cache_;

private:
  SomeDataType
  buildCache_()
  {
    // expensive cache construction
    // fill this->cache_ explicitly
    return cache_;
  }

}

这样做的缺点是 buildCache_() 不能是 const。此外,海湾合作委员会提示说

warning: ‘B::cache_’ should be initialized in the member initialization list [-Weffc++]

有没有更合适的解决方案?

最佳答案

你所做的事情是未定义的行为,来自[class.base.init]/14,强调我的:

Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.

您想要做的是使用 Base-from-Member idiom :

class Cache {
protected:
    const SomeDataType cache_;
};

class B : private Cache, public A {
public:
    B() : Cache(), A(cache_)
    { }
};

关于c++ - 使用派生类成员进行父类的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30438446/

相关文章:

c++ - DLL 的全局变量存储在内存中的什么位置?

ios - 没看懂swift编程中initialize的过程

c++ - 如何在 C++ 中同时子类化多个类?

javascript - 为什么在 javascript 中过滤扩展数组的类的对象调用它的构造函数?

c++ - 高斯模糊永远无法正常工作

c++ - 动态内存,堆栈内存和静态内存与c++的区别?

c# - .Net 如何在 Webbrowser 中获取被点击元素的 ID

javascript - Meteor.js Google map 初始化

swift - 子类化格式化程序在初始化程序上崩溃

c++ - 将派生类作为值放入 STL 映射中