2013-01-08 28 views
1

我正在寫一個C++應用,其中我有一個Controller類具有兩個嵌套的結構,在我的頭文件中定義如下:缺少構造函數 - 但我沒有調用它?

class Controller { 
    struct help_message { // controller.hpp, line 19 
     std::string summary; 
     std::string details; 
     help_message(const std::string&, const std::string&); 
    }; 

    struct player_command { 
     cmd_t cmd; 
     help_message help; 
     // cmd_t is my own typedef, irrelevant for this question 
     player_command(const cmd_t&, const help_message&); 
    }; 

    // more members... 
}; 

以我的源文件,我有這樣的:

Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) { 
    cmd = c; 
    help = h; 
}; 

Controller::help_message::help_message(const std::string& s, const std::string& d) { 
    summary = s; 
    details = d; 
}; 

,我認爲是很好,但是當我編譯,這是我所得到的(controller.cpp線12的源代碼段的第一線以上):

g++ -g -Wall -std=c++0x -c -o controller.o controller.cpp 
controller.cpp: In constructor ‘palla::Controller::player_command::player_command(void (palla::Controller::* const&)(const args_t&), const palla::Controller::help_message&)’: 
controller.cpp:12:93: error: no matching function for call to ‘palla::Controller::help_message::help_message()’ 
controller.cpp:12:93: note: candidates are: 
In file included from controller.cpp:7:0: 
controller.hpp:22:3: note: palla::Controller::help_message::help_message(const string&, const string&) 
controller.hpp:22:3: note: candidate expects 2 arguments, 0 provided 
controller.hpp:19:9: note: palla::Controller::help_message::help_message(const palla::Controller::help_message&) 
controller.hpp:19:9: note: candidate expects 1 argument, 0 provided 
controller.hpp:19:9: note: palla::Controller::help_message::help_message(palla::Controller::help_message&&) 
controller.hpp:19:9: note: candidate expects 1 argument, 0 provided 
make: *** [controller.o] Error 1 

根據我的推論,編譯器在某處嘗試調用help_message的缺省構造函數,該構造函數不存在。然後它會嘗試將調用與我創建的構造函數以及生成的複製構造函數和賦值運算符進行匹配,並根據參數個數對每個構造函數進行失敗。

但是我的代碼中有哪部分調用了默認構造函數?我該如何解決這個錯誤?

+1

已經回答得很好了,但是換一種方式:每一個構造函數首先構造所有子對象* *前的'{}'標記進入體內。如果你不說如何,它會嘗試默認的構造函數。所以你不妨說一下如何使用mem-initializer-list。 – aschepler

回答

7

player_command()構造函數首先默認構造help,然後分配給它:

Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) { 
    cmd = c; 
    help = h; 
}; 

修改成:

Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) 
: cmd(c), 
    help(h) 
{ 
}; 

Benefits of Initialization lists

+0

微妙的錯誤(至少對我來說) - 快速捕捉和很好的解釋。獎勵! –

+1

不是一個錯誤。初始化和賦值之間只有一個(不太微妙的)區別。 –

0

您沒有使用避免了語法複製構造函數。這個參數是通過引用傳遞的(沒有拷貝構造函數),但是在分配給伊娃時它確實被拷貝了。

Class::Class(const Variable &var) { 
    this->var = var; // assignment here, this invokes copy contructor! 
} 

應使用以下語法:

Class::Class(const Variable &var) : var(var) { } 
3

player_command結構包含一個help_message(幫助),並沒有爲help_message沒有默認構造函數。當調用構造函數player_command時,默認情況下,幫助成員變量將被默認構造。您立即將幫助分配給給定的參數,但是這會在默認構建後進行。相反,改變構造函數是這樣的:

Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) : cmd(c), help(h) 
{} 

這將調用兩個cmd並幫助成員變量而不是做默認的建設和分配,然後拷貝構造函數。

相關問題