【问题标题】:C++ class: must explicitly initialize the memberC++ 类:必须显式初始化成员
【发布时间】:2023-03-18 20:23:01
【问题描述】:

所以,我创建了一个名为“Grid”的类。我也有一门课叫做'Field'。 Field-class 有 4 个 Grid 类型的变量,它们都在构造函数中设置。除了,它们不是……或者至少编译器不这么认为。

我真的不明白为什么,我将所有变量设置为一个新实例。

当我将鼠标悬停在红色下划线(在构造函数下)时,它会说: "'Field' 的构造函数必须显式初始化没有默认构造函数的成员 'b_attack'"

代码:

class Grid{
    friend class Field;
private:
    unsigned int xSize;
    unsigned int ySize;
    bool *ptrfield;
    Grid(unsigned int xSize, unsigned int ySize){
        this->xSize = xSize;
        this->ySize = ySize;
        ptrfield = new bool[xSize*ySize];
    }
};

class Field{
private:
    Grid a_own;
    Grid a_attack;
    Grid b_own;
    Grid b_attack;
public:
    Field(unsigned int xSize, unsigned int ySize){
        a_own = Grid(xSize, ySize);
        a_attack = Grid(xSize, ySize);
        b_own = Grid(xSize, ySize);
        b_attack = Grid(xSize, ySize);
    }
    void print(){
        std::cout << "aHELLO" << std::flush;
        std::cout << a_own.xSize << std::flush;
    }
}; 

【问题讨论】:

  • 考虑使用std::vector 进行阵列存储。你在这里使用new[],但没有对应的delete[],所以这会泄漏内存,这是一个不好的习惯。 std::vector 会为您解决这些问题。
  • @tadman 是的,我想在编译完这个东西后这样做... //TODO

标签: c++ class variables constructor initialization


【解决方案1】:

问题是您的 4 个 Grid 成员对象是在 你的 Field 构造函数的主体被输入之前创建的(或者至少,编译器想要生成代码来创建它们 - 但它不能);见this cppreference(我的粗体字):

在构成函数体的复合语句之前 构造函数开始执行,初始化所有直接基, 虚拟基础,并且非静态数据成员已完成。成员 初始化列表是非默认初始化的地方 可以指定这些对象。对于不能成为的成员 默认初始化,例如引用成员和 const-qualified 类型,必须指定成员初始值设定项。没有初始化是 为不具有 成员初始化器。

从这个引用(关于“不能默认初始化的成员”的注释),我们可以看到我们可以在初始化列表中提供所需的初始化; this 紧跟在构造函数声明的结束 ) 之后,使用 : 后跟所需的逗号分隔的初始化程序。像这样,在你的情况下:

    Field(unsigned int xSize, unsigned int ySize) : // The ":" starts our initializer list
        a_own(xSize, ySize),      // .. and each one of these constructs a "Grid"
        a_attack(xSize, ySize),
        b_own{ xSize, ySize },    // This "{...}" form is newer and many prefer it,
        b_attack{ xSize, ySize }  // but it can also be a bit confusing
    {
        return; // We now have nothing left to do in the actual "body" of the c'tor!
    }

请随时要求进一步澄清和/或解释。

PS:对于您发布的代码,我的编译器给出了您为所有四个Grid 成员报告的错误;也许你的在第一个之后就“放弃”了?

【讨论】:

  • 由于某种原因,我无法使用“新表单”。它说:{预期的成员名称或';'在声明说明符} 之后。但另一个有效!谢谢!
  • @NikitaDemodov 然后很幸运我给出了两种形式的例子!我认为{...} 形式是在 C++11 标准中出现的;如果你的编译器使用的是 C++98,它们肯定不会工作。
猜你喜欢
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多