2012-08-30 13 views
57

私はC++ 11標準を試し始めましたが、同じクラスの別のctorからctorを呼び出す方法を説明するthisという質問があります。デリゲートされたコンストラクタを使用している間のメンバの初期化

HPP:

class Tokenizer 
{ 
public: 
    Tokenizer(); 
    Tokenizer(std::stringstream *lines); 
    virtual ~Tokenizer() {}; 
private: 
    std::stringstream *lines; 
}; 

CPP:

Tokenizer::Tokenizer() 
    : expected('=') 
{ 
} 

Tokenizer::Tokenizer(std::stringstream *lines) 
    : Tokenizer(), 
    lines(lines) 
{ 
} 

しかし、これは私にエラーを与えている: In constructor ‘config::Tokenizer::Tokenizer(std::stringstream*)’: /path/Tokenizer.cpp:14:20: error: mem-initializer for ‘config::Tokenizer::lines’ follows constructor delegation私はきた今、私はこのようなコードと同じことをしようとしていますTokenizer()の部分をリストの最初と最後に移動しようとしましたが、それは助けになりませんでした。

これの背後にある理由は何ですか。どのように修正する必要がありますか?私は代わりにthis->lines = lines;lines(lines)体に移動しようとしたとうまく動作します。しかし、私は本当に初期化リストを使用できるようにしたいと思います。

ありがとうございます!

答えて

76

あなたが別のコンストラクタにメンバーの初期化を委任する場合、他のコンストラクタは(すなわち、あなたの例ではlines部材を含む)すべてのメンバーを含むオブジェクト完全を初期化することを前提があります。したがって、メンバーのいずれかを再度初期化することはできません。

(§12.6.2/6) A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-decltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class, it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the is the target constructor. [...]

あなたは仕事アラウンドすることができます。この引数に取るコンストラクタのバージョン最初定義することによって:

Tokenizer::Tokenizer(std::stringstream *lines) 
    : lines(lines) 
{ 
} 

標準からの関連の引用は(強調鉱山)であります委譲を使用してデフォルトコンストラクタを定義します。

Tokenizer::Tokenizer() 
    : Tokenizer(nullptr) 
{ 
} 

原則として、最大数の引数をとり、他のバージョンからデリゲートするコンストラクタのバージョンを完全に指定する必要があります(委任で引数として目的のデフォルト値を使用)。

+2

最初は逆立ちそうですが、実際には実際に役立っています! – Korchkidu

関連する問題