C ++中的Base-from-Member Idiom

时间:2011-01-27 11:51:13

标签: c++ idioms ostream initialization-list

以下代码来自here

#include <streambuf>  // for std::streambuf
#include <ostream>    // for std::ostream

class fdoutbuf
    : public std::streambuf
{
public:
    explicit fdoutbuf( int fd );
    //...
};

class fdostream
    : public std::ostream
{
protected:
    fdoutbuf buf;
public:
    explicit fdostream( int fd ) 
        : buf( fd ), std::ostream( &buf ) // This is not allowed. 
                                          // buf can't be initialized before std::ostream.
        {}
    //...
};

我真的不明白这个评论。为什么“buf无法在std :: ostream之前初始化”?我能用一些帮助来理解这个吗?

2 个答案:

答案 0 :(得分:6)

初始化的顺序由声明类成员的顺序决定,并且继承的类在所有这些之前。举一个简单的例子来说明基本问题而不参考继承:

class C
{
  int a, b;
public:
  C() : b(1), a(b) {} // a is initialized before b!
};

代码不符合你的想法!首先初始化a,然后将b初始化为1。所以它取决于声明的顺序而不是初始化列表中的顺序:

int a, b;

现在,同样的想法适用于在派生类成员之前初始化的基类。要解决此问题,请创建一个您固有的类,其中包含要从基类初始化的成员。当然,那个辅助类必须在你实际派生的那个之前。

答案 1 :(得分:3)

在初始化成员变量之前,必须调用基类构造函数,但是将指针传递给buf(此时未定义的成员变量)到此构造函数。