我目前面临以下情况:

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

如您所见,foobar的设计用途如下:
foo f ( /* some parameters */ );
bar b ( f );

但是,我希望包装器类在需要时是独立的,而derived2必须是独立的。但是,derived2::m_foo不能在未初始化时仅传递给base

所以我的问题是:有没有一种方法可以强制derived2::m_foobase之前构造?

我想到的唯一解决方案是:
class derived2_foo
{
protected:
    foo m_foo;
};

class derived2 : public base, public derived2_foo
{
public:
    derived2 () : derived2_foo (), base ( m_foo ) {}
};

哪个应该是有效的代码(我可以随意证明是错误的),但是我不确定我是否喜欢这种解决方案。因此,我在这里寻求其他想法。

最佳答案

您的基本想法是一个好主意,但是您应该使用私有(private)继承,以便derived2的客户端不知道内部发生了什么。

class derived2_foo
{
protected:
    foo m_foo;
};

class derived2 : private derived2_foo, public base
{
public:
    derived2 () : derived2_foo(), base ( m_foo ) {}
};

我还更改了基类在类声明中出现的顺序。始终确保类声明中的顺序与初始化列表中的顺序匹配(就像成员变量一样)。正如C++ FAQ所说:



或什至更正式的资料,请参见§12.6.2/ 13.2的C++标准:



另一个改进是将derived2_foo类放入其自己的“私有(private)” namespace :
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命名空间从技术上讲不会隐藏或保护任何内容,但它会向客户端发出信号,表明它们不应依赖于其内容。

09-06 13:48