我目前面临以下情况:
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 );
但是,如果需要,我希望我的包装类是独立的,并且 衍生2
需要是独立的。但是,衍生2::m_foo
不能在未初始化时直接传递给base
。
所以我的问题是:有没有办法强制 衍生2::m_foo
在 base
之前构造?
我自己想出的唯一解决方案是:
class derived2_foo
{
protected:
foo m_foo;
};
class derived2 : public base, public derived2_foo
{
public:
derived2 () : derived2_foo (), base ( m_foo ) {}
};
这应该是有效的代码(我可以自由地被证明是错误的),但我不太确定我是否想要喜欢这个解决方案。所以我来这里是为了寻找其他想法。
最佳答案
您的基本想法是好的,但您应该使用私有(private)继承,以便 衍生2
的客户端不知道内部发生了什么。
class derived2_foo
{
protected:
foo m_foo;
};
class derived2 : private derived2_foo, public base
{
public:
derived2 () : derived2_foo(), base ( m_foo ) {}
};
我还更改了基类在类声明中出现的顺序。始终确保类声明中的顺序与初始化列表中的顺序匹配(就像成员变量一样)。作为C++ FAQ说:
Note that the order B1 and then B2 [...] is determined by the order that the base classes appear in the declaration of the class, not in the order that the initializer appears in the derived class’s initialization list.
或者对于更官方的来源,C++ 标准位于 §12.6.2/13.2:
[...] direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
另一个改进是将衍生2_foo
类放入它自己的“私有(private)”命名空间中:
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++ - 强制在基类之前构造成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32934179/