1

Controller次のようにヘッダー ファイルで定義された 2 つのネストされた構造体を持つクラスを持つ C++ アプリケーションを作成しています。

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、存在しないデフォルトのコンストラクタを呼び出そうとしています。次に、作成したコンストラクター、生成されたコピー コンストラクターおよび代入演算子と呼び出しを一致させようとし、引数の数でそれぞれ失敗します。

しかし、私のコードのどの部分が既定のコンストラクターを呼び出しているのでしょうか? そして、どうすればこのエラーを修正できますか?

4

3 に答える 3

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)
{
};

初期化リストの利点を参照してください

于 2013-01-08T16:14:00.807 に答える
3

player_command構造体にはhelp_message(ヘルプ)が含まれており、のデフォルトのコンストラクターはありませんhelp_messageplayer_commandコンストラクターが呼び出されると、デフォルトでヘルプメンバー変数がデフォルトで作成されます。指定されたパラメーターにすぐにヘルプを割り当てますが、これはデフォルトで作成された後です。代わりに、コンストラクターを次のように変更します。

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

これにより、デフォルトの構築と割り当てを行う代わりに、cmdとhelpの両方のメンバー変数のコピーコンストラクターが呼び出されます。

于 2013-01-08T16:17:10.787 に答える
0

コピー コンストラクターを回避する構文を使用していません。引数は参照渡し (コピー コンストラクターなし) ですが、ivar に割り当てられると実際にコピーされます。

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

次の構文を使用する必要があります。

Class::Class(const Variable &var) : var(var) { }
于 2013-01-08T16:15:56.413 に答える