私はC++ 11標準を試し始めましたが、 this initメソッドなどを避けるために同じクラスの別のctorからあなたのctorを呼び出す方法を説明する質問を見つけました。今、私はこのようなコードで同じことを試みています:
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)
を本体に移動しようとしましたが、正常に動作します。しかし、私は本当に初期化子リストを使用できるようにしたいと思います。
前もって感謝します!
メンバーの初期化を別のコンストラクターに委任すると、他のコンストラクターがオブジェクトを初期化するという前提がありますcompletely(すべてのメンバーを含む(例ではlines
メンバーを含む)。したがって、メンバーを再度初期化することはできません。
標準からの関連する引用は(強調鉱山)です:
(§12.6.2/ 6)mem-initializer-listは、コンストラクターのクラス自体を示すclass-or-decltypeを使用して、コンストラクターのクラスの別のコンストラクターに委任できます。 mem-initializer-idがコンストラクターのクラスを指定する場合、唯一のmem-initializer;コンストラクターは委任コンストラクターであり、によって選択されたコンストラクターはターゲットコンストラクターです。 [...]
これを回避するには、引数を取るコンストラクタのバージョンを定義しますfirst:
Tokenizer::Tokenizer(std::stringstream *lines)
: lines(lines)
{
}
次に、委任を使用してデフォルトのコンストラクタを定義します。
Tokenizer::Tokenizer()
: Tokenizer(nullptr)
{
}
一般的な規則として、引数の最大数をとるコンストラクターのバージョンを完全に指定し、他のバージョンから委任します(委任で引数として目的のデフォルト値を使用)。