Дефолтный конструктор. Ограничения
#новичкам
Мы уже краем уха задевали эту тему, но сегодня поговорим основательно. Вот все причины, почему дефолтный конструктор не может неявно сгенерироваться компилятором:
1️⃣
У класса есть другие конструкторы
class ParametrizedConstructor {
int total;
public:
ParametrizedConstructor(int initial_value) : total(initial_value) { };
void accumulate (int x) { total += x; };
};
Example2 ex (100); // ok
Example2 ex1; // error: no default constructor
Даже если вы сами определили copy/move конструктор руками, конструктор по-умолчанию неявно генерироваться не будет:
struct UserCopyConstructor
{
UserCopyConstructor(const UserCopyConstructor&) {}
// UserCopyConstructor::UserCopyConstructor() is implicitly defined as deleted
};
struct UserMoveConstructor
{
UserMoveConstructor(UserMoveConstructor&&) = default;
// UserMoveConstructor::UserMoveConstructor() is implicitly defined as deleted
};
2️⃣
В классе есть нестатическое поле-ссылка.
Ссылка обязательно должна быть инициализирована объектом, а это невозможно сделать, не имея объект.
struct HasReference {
int& ref; // error: reference needs to be initialized
};
3️⃣
В классе есть нестатическое константное поле с тривиальным конструктором по-умолчанию. Тривиальные конструкторы по сути вообще ничего не делают, кроме как начинают лайфтайм объекта. То есть все поля
заполняются мусором.
Но для константных объектов подразумевается наличие определенного постоянного значения. Мусорные значения не удовлетворяют этому требованию.
struct ConstTrivial {
const int x; // int has a trivial default constructor, so cannot default construct an object
};
Тем не менее,
компилятор спокойно может проглотить константный член с нетривиальным дефолтным конструктором. Считается, что такой конструктор корректно инициализирует объект:
struct ConstNonTrivial {
const std::string s; // std::string has non-trivial constructor
};
ConstNonTrivial cnt; // OK, s is just empty string
4️⃣
Если какой-то член класса или базовый класс имеет недоступный (private) или удалённый (= delete) конструктор по умолчанию
struct NoDefault {
private:
NoDefault() {} // private constructor
};
struct Derived : NoDefault {
// Derived() is implicitly deleted
};
struct DeletedDefault {
DeletedDefault() = delete; // explicilty deleted
};
struct HasDeleted {
DeletedDefault dd;
};
HasDeleted hd; // ERROR! dd has explicilty deleted default constructor
Если знаете еще способы, пишите в комментах.
Don't be trivial. Stay cool.
#cppcore
Обсуждение 18
Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.
Обсудить в Telegram