I'm writing a C++ application in which I have a Controller
class with two nested structs, defined in my header file as follows:
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...
};
In my source file, I have this:
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;
};
which I thought was fine, but when I compile, this is what I get (controller.cpp line 12 is the first line of the source snippet above):
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
From what I can deduce, the compiler is somewhere trying to call the default constructor of help_message
, which doesn't exist. It then tries to match the call up with the constructor I created as well as with the generated copy-constructor and assignment operator, and failing each on the number of arguments.
But what part of my code is calling a default constructor? And how do I fix this error?
The player_command()
constructor first default constructs help
and then assigns to it:
Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) {
cmd = c;
help = h;
};
Change that to:
Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h)
: cmd(c),
help(h)
{
};
The player_command
struct contains a help_message
(help), and there is no default constructor for help_message
. When the player_command
constructor is called, by default the help member variable will be default constructed. You are immediately assigning help to the given parameter but this will be after it is default constructed. Instead change the constructor to be something like:
Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) : cmd(c), help(h)
{}
This will invoke the copy constructor for both cmd and help member variables instead of doing default construction and then assignment.
You are not using the syntax which avoids the copy constructor. The argument is passed by reference (no copy constructor) but it is indeed copied when assigned to the ivar.
Class::Class(const Variable &var) {
this->var = var; // assignment here, this invokes copy contructor!
}
You should use the following syntax:
Class::Class(const Variable &var) : var(var) { }
来源:https://stackoverflow.com/questions/14219242/default-constructor-missing-but-im-not-calling-it