#c #oop #destructor
#c #ооп #деструктор
Вопрос:
Скажем, в качестве упрощенного примера у меня есть объект класса House, в котором также есть объект Kitchen.
Вот файл заголовка:
class Kitchen {
private:
int width;
int height;
int length;
public:
Kitchen(int width, height, length); // default constructor
};
class House {
private:
int houseId;
Kitchen newKitchen;
public:
House(Kitchen newKitchen, int houseId); // default constructor
Houseamp; operator=(House constamp; other); // copy assignment
House(House constamp; other); // copy constructor
~House(); // destructor
};
Копирование houseId
отлично работает в функции назначения копирования. Но я получаю сообщение об ошибке, относящееся к House::House(House constamp; other) { *this = other; }
следующему:
error: constructor for 'House' must explicitly initialize the member 'newKitchen' which does not have a default constructor
в чем я не уверен, поскольку я думал, что мое объявление конструктора по умолчанию охватывает это?
Комментарии:
1. Если все в членах вашего класса тривиально копируется, лучший выбор — вообще не писать конструктор копирования. Компилятор генерирует его по умолчанию.
2. … и
Kitchen(int width, height, length);
иHouse(Kitchen newKitchen, int houseId);
не являются конструкторами по умолчанию.3. Примечание: обычно проще, чтобы оператор присваивания использовал конструктор копирования, а не наоборот. Когда у вас есть члены или базовые классы, которые требуют инициализации, присваивание не может его сократить.
Ответ №1:
Во-первых, ваш «конструктор по умолчанию» в Kitchen
не является конструктором по умолчанию, это определяемый пользователем конструктор. Он должен инициализировать элементы, а также я бы повторно включил копирование и перемещение, следуя правилу пяти.
class Kitchen {
private:
int width;
int height;
int length;
public:
// Use member initialization list
Kitchen(int _width, int _height, int _length) : width(_width), height(_height), length(_length) {}
// Rule of 5
Kitchen(Kitchen constamp;) = default;
Kitchenamp; operator=(Kitchen constamp;) = default;
Kitchen(Kitchenamp;amp;) = default;
Kitchenamp; operator=(Kitchenamp;amp;) = default;
};
Затем позже вы House
сможете использовать этот пользовательский конструктор аналогичным образом
House(Kitchen _newKitchen, int _houseId) : houseId(_houseId), newKitchen(_newKitchen) {}
Обратите внимание, что ваш Kitchen
может быть просто агрегированным типом POD, чтобы избежать проблем
class Kitchen
{
public:
int width;
int height;
int length;
}
Это будет следовать «правилу нуля» и будет по умолчанию конструируемым, агрегируемым инициализируемым, копируемым и перемещаемым. То же самое будет следовать и для вашего House
класса.
Комментарии:
1. Привет, большое спасибо за ваш комментарий. Я попытался реализовать то, что вы предложили, и я все еще получаю те же ошибки. Я создал список инициализаторов для House и Kitchen в своих пользовательских конструкторах
2. @mlan Если вы реализовали то, что предложил Кори, вы не можете получить ту же ошибку. ДЕМОНСТРАЦИЯ