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

Error C2512: no appropriate default constructor available - Why if properties are being initialized in constructor?

本文关键字:构造函数 如果 初始化 为什么 属性 错误 默认 C2512      更新时间:2023-10-16

我已经搜索了很长一段时间,找不到任何与我处境相同的人。如果这是重复的,很抱歉。

我有一个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):错误C2512:"引擎":没有合适的默认构造函数可用

如果属性在构造函数中初始化,为什么好的,我理解Chris关于初始化列表的评论。我该如何评估argc和所有这些来初始化Stage?

只要类中有字段,就会有一个不带参数的隐式构造。如果你想使用非默认构造函数初始化字段,你必须使用初始化器,比如:

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

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

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

在成员初始化之前,有一种更好的方法可以进行复杂的处理,而不会使对象的生存期因指针而变得复杂:

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});
相关文章: