错误C2512:没有合适的默认构造函数 - 为什么在构造函数中初始化属性?

时间:2014-04-25 03:01:01

标签: c++ constructor attributes

我现在已经搜索了很长一段时间,在我的情况下无法找到任何人。对不起,如果这是重复的。

我有一个游戏类,在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):错误C2512:'引擎' :没有合适的默认构造函数

为什么在构造函数中初始化属性? 好的,我理解克里斯关于初始化列表的评论。我怎样才能设法评估argc以及初始化Stage的所有内容?

2 个答案:

答案 0 :(得分:2)

只要在类中有字段,就会有一个没有参数的隐式构造。如果要使用非默认构造函数初始化字段,则必须使用初始值设定项,如下所示:

Game::Game(int argc, char **argv) : logger(), 
                                    stage(fileName), 
                                    engine(stage.getWidthPx(), 
                                           stage.getHeightPx(), 
                                           bitsPerPixel, 
                                           stage.getTimeStep())
{
     /* remainder of constructor here */
}

除非这可能不起作用,因为你可能在构造函数中做了一些工作来初始化fileNamebitsPerPixel。但这是你遇到的问题。你如何解决这个问题取决于你。

每个构造函数都必须为类中的每个字段调用构造函数。如果您没有指定哪个构造函数,那么它将是默认构造函数。但是,您可以将字段指向对象。然后他们可以初始化为NULL,你可以在构造函数中使用new创建它们。

答案 1 :(得分:1)

这是在成员初始化之前进行复杂处理的一种更好的方法,而不会使指针的对象生命周期变得复杂:

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