错误 C2512:没有适当的默认构造函数可用 - 为啥在构造函数中初始化属性?
Posted
技术标签:
【中文标题】错误 C2512:没有适当的默认构造函数可用 - 为啥在构造函数中初始化属性?【英文标题】:Error C2512: no appropriate default constructor available - Why if properties are being initialized in constructor?错误 C2512:没有适当的默认构造函数可用 - 为什么在构造函数中初始化属性? 【发布时间】:2014-04-25 03:01:01 【问题描述】:我已经搜索了很长一段时间,但找不到像我这样的人。抱歉,如果这是重复的。
我有一个 Game 类,在 Game.h 中定义:
class Game
public:
Game(int argc, char **argv);
~Game();
private:
Logger logger;
Stage stage;
Engine engine;
;
然后在 Game.cpp 中:
Game::Game(int argc, char **argv)
// Some code removed for clarity. Consider filename and bitsPerPixel
// already defined.
string fileName;
if (argc != 2)
fileName = defaultYAMLFilename;
logger.logBadParam(argc, fileName);
else
fileName = argv[1];
logger = Logger();
stage = Stage(fileName);
engine = Engine(stage.getWidthPx(), stage.getHeightPx(), bitsPerPixel, stage.getTimeStep());
然后我得到这个错误:
game.cpp(7): 错误 C2512: 'WormsModel::Stage' : 没有合适的默认构造函数可用
game.cpp(7): error C2512: 'Engine' : 没有合适的默认构造函数可用
为什么要在构造函数中初始化属性?
好的,我了解 Chris 关于初始化列表的评论。我怎样才能设法评估 argc 以及初始化 Stage 的所有内容?
【问题讨论】:
这些是赋值,而不是初始化。使用构造函数初始化列表。 【参考方案1】:只要类中有字段,就会有一个没有参数的隐式构造。如果要使用非默认构造函数初始化字段,则必须使用初始化器,如下所示:
Game::Game(int argc, char **argv) : logger(),
stage(fileName),
engine(stage.getWidthPx(),
stage.getHeightPx(),
bitsPerPixel,
stage.getTimeStep())
/* remainder of constructor here */
除非这可能行不通,因为您可能在构造函数中做了一些工作来初始化fileName
和bitsPerPixel
。但这是您遇到的问题。如何解决它取决于您。
每个构造函数都必须为类中的每个字段调用一个构造函数。如果您不指定哪个构造函数,它将是默认值。但是,您可以使字段指针指向对象。然后它们可以初始化为 NULL,您可以在构造函数中使用 new 创建它们。
【讨论】:
感谢您的回答。据我所知,您也没有在构造函数或其他方法中创建这些字段的选项。您必须在标题中声明它们。所以我在这里别无选择,对吗? 是的,我想我应该更清楚地说明这一点。每个构造函数都必须为类中的每个字段调用一个构造函数。如果您不指定哪个构造函数,它将是默认值。但是,您可以使字段指针指向对象。然后它们可以初始化为 NULL,您可以在构造函数中使用new
创建它们。
谢谢,这就是解决方案。我已经在更改 Stage 和 Engine 构造函数,我不喜欢这样做。非常感谢
@BenVoigt 指针可能不是解决此问题的最佳方法。但有时指针是一个很好的答案。【参考方案2】:
这是在成员初始化之前进行复杂处理的更好方法,而不会使指针的对象生命周期变得复杂:
struct GameOptions
std::string YAMLFilename;
GameOptions(int argc, char** argv);
;
GameOptions::GameOptions(int argc, char** argv)
if (argc != 2)
YAMLFilename = defaultYAMLFilename;
logger.logBadParam(argc, fileName);
else
YAMLFilename = argv[1];
Game::Game(GameOptions&& opts) : logger()
, stage(opts.YAMLFilename )
, engine(stage.getWidthPx(),
stage.getHeightPx(),
bitsPerPixel,
stage.getTimeStep())
/* remainder of constructor here */
并将其称为
Game theGame(GameOptions(argc, argv));
甚至
Game theGame(argc, argv);
【讨论】:
以上是关于错误 C2512:没有适当的默认构造函数可用 - 为啥在构造函数中初始化属性?的主要内容,如果未能解决你的问题,请参考以下文章