2012-08-30 103 views
57

我已經開始嘗試使用C++ 11標準,並且發現this問題,它描述瞭如何從同一個類中的另一個ctor調用您的ctor以避免使用init方法等。現在,我想用代碼同樣的事情,看起來像這樣:使用委託構造函數的成員初始化

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()第一個和最後一個列表中的部分,但沒有幫助。

背後的原因是什麼,我該如何解決?我已經嘗試將lines(lines)移動到身體this->lines = lines;而不是它的工作正常。但我真的很想能夠使用初始化列表。

在此先感謝!

回答

76

當你委託成員初始化至另一個構造,則存在其他構造初始化對象完全,包括所有成員(即包括在您的示例lines構件)的假設。因此您不能再次初始化任何成員。

從標準的相關報價(重點礦山):

Tokenizer::Tokenizer(std::stringstream *lines) 
    : lines(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() 
    : Tokenizer(nullptr) 
{ 
} 

作爲一般規則,您應完全指定具有最大參數數量的構造函數版本,然後從其他版本進行委派(使用所需的默認值作爲委派中的參數)。

+2

起初它似乎是反直覺,但實際上真的有幫助! – Korchkidu

相關問題