Класс C ++: должен явно инициализировать член - PullRequest
1 голос
/ 29 апреля 2020

Итак, я создал этот класс под названием «Сетка». У меня также есть класс под названием «Поле». У Field-класса есть 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;
    }
}; 

1 Ответ

3 голосов
/ 29 апреля 2020

Проблема состоит в том, что ваши 4 Grid объекты-члены создаются до тела вашего конструктора Field (или, по крайней мере, компилятор хочет для генерации кода создать их - но не может); см. this cppreference (выделение жирным шрифтом):

Прежде чем составной оператор, который формирует тело функции конструктора, начинает выполнять , инициализацию всех прямых баз, виртуальные базы и non-stati c членов данных завершено . Список инициализаторов членов - это место , где можно указать инициализацию этих объектов по умолчанию. Для элементов, которые не могут быть инициализированы по умолчанию , таких как ссылочные члены и типы с константной квалификацией, должны быть указаны инициализаторы элементов. Не выполняется инициализация для анонимных объединений или вариантов членов, которые не имеют инициализатора элемента.

Из этой цитаты (замечания о «элементах, которые не могут быть инициализированы по умолчанию») мы видим, что мы может обеспечить требуемую инициализацию в списке инициализаторов; он помещается сразу после закрытия ) объявления конструктора, используя :, за которым следуют обязательные инициализаторы, разделенные запятыми. Например, в вашем случае:

    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 членов; может быть, ваш "сдается" после первого?

...