2

次のコードはここからです:

#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の前に初期化できない」のはなぜですか?これを理解するのに役立つことはありますか?

4

2 に答える 2

8

初期化の順序は、クラスメンバーを宣言する順序によって決定され、継承されたクラスはそのすべての前に配置されます。継承を参照せずに基本的な問題を説明する簡単な例を見てみましょう。

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

コードはあなたが思うことをしません!aが最初に初期化され、次にbが1に初期化されます。したがって、初期化リストの順序ではなく、宣言の順序に依存します。

int a, b;

現在、同じ考え方が、派生クラスメンバーの前に初期化される基本クラスにも当てはまります。この問題を解決するには、基本クラスから初期化するメンバーを含む固有のクラスを作成します。もちろん、そのヘルパークラスは、実際に派生しているクラスの前に来る必要があります。

于 2011-01-27T11:59:38.463 に答える
3

メンバー変数を初期化する前に基本クラスコンストラクターを呼び出す必要がありますが、buf(この時点では未定義のメンバー変数)へのポインターをこのコンストラクターに渡します。

于 2011-01-27T11:55:53.107 に答える