强制成员变量在基类之前构造
Force member variable to be constructed before base class
我目前面临以下情况:
class foo
{
public:
foo ( /* some parameters */ );
};
class bar
{
public:
bar ( foo & f );
};
// both foo and bar are 3rd party
class base
{
public:
base ( foo & f ) : m_bar ( f ) {}
private:
bar m_bar;
};
class derived : public base
{
public:
derived ( foo & f ) : base ( f ) {}
};
class derived2 : public base
{
public:
derived2 () : base ( /* well ... */ ) {}
private:
foo m_foo;
};
可以看到,foo
和bar
被设计成这样使用:
foo f ( /* some parameters */ );
bar b ( f );
然而,如果需要的话,我希望我的包装器类是独立的,derived2
需要是。但是,derived2::m_foo
不能在未初始化时直接传递给base
。
所以我的问题是:有没有一种方法可以强制derived2::m_foo
在base
之前构建?
我自己想到的唯一解决办法是:
class derived2_foo
{
protected:
foo m_foo;
};
class derived2 : public base, public derived2_foo
{
public:
derived2 () : derived2_foo (), base ( m_foo ) {}
};
这应该是有效的代码(我可以自由地被证明是错误的),但我不太确定如果我想喜欢这个解决方案。所以我在这里寻找其他的想法。
你的基本想法是好的,但是你应该使用私有继承,这样derived2
的客户端就不知道里面发生了什么。
class derived2_foo
{
protected:
foo m_foo;
};
class derived2 : private derived2_foo, public base
{
public:
derived2 () : derived2_foo(), base ( m_foo ) {}
};
我还改变了基类在类声明中出现的顺序。始终确保类声明中的顺序与初始化列表中的顺序匹配(就像成员变量一样)。正如c++ FAQ所说:
注意顺序B1和B2[…]是由类的声明中基类出现的顺序类中而不是的初始化项出现在派生类中的顺序类的初始化列表
或者更官方的来源,c++标准§12.6.2/13.2:
[…直接基类按声明顺序初始化出现在基本指定符列表中(无论元素的顺序如何) mem-initializers )。
另一个改进是将derived2_foo
类放入其自己的"私有"命名空间:
namespace detail
{
class derived2_foo
{
protected:
foo m_foo;
};
}
class derived2 : private detail::derived2_foo, public base
{
public:
derived2 () : derived2_foo(), base ( m_foo ) {}
};
像Boost这样的库也会这样做。虽然detail
名称空间在技术上并不隐藏或保护任何内容,但它向客户机发出信号,表明它们不应该依赖于其内容。
相关文章:
- 派生类看不到基类成员
- C++11: 如何访问派生类中的基类成员?
- Qml 未收到基类成员变量的更新值
- 指向从指针派生类成员函数的指针,指向基类成员函数
- 初始化基类成员 (c++) 的首选方法
- 访问多级复合关系中的基类成员
- 允许从特定派生类访问基类成员
- 在派生类的成员联合中包含继承的基类成员
- 由派生类设置的 constexpr 基类成员
- 从派生类调用的抽象基类成员函数
- 从抽象基类访问另一个基类成员
- C++派生类访问基类成员
- 不能引用派生模板类中的基类成员
- C2694 在析构函数上,当基类成员的析构函数具有非空 noexcept 说明符和主体时
- 在Visual Studio 2017中,通过扩展每个参数包来呼叫基类成员失败
- 在C 中访问带有不正确的下属的基类成员
- C++将基类成员链接到派生类成员
- 从基类成员函数返回派生类的实例
- 从指针到基类成员的模板推导
- 是否可以从派生类中排除基类成员?