Для конструктора по умолчанию,
чем пустое тело отличается от того что получается с =default?
X::X() {}
// и
X::X() = default;
Ответ
Наличие конструктора по умолчанию с пустым телом автоматически делает класс нетривиальным. Со всеми вытекающими отсюда особенностями. Например делает тип не POD. А также исключает возможность использовать агрегатную инициализацию:
#include
struct X {
//X() {}
X() = default;
int a;
int b;
};
int main( ) {
X x { 1, 2 }; // ошибка, если X - не тривиальный класс.
std::cout << std::boolalpha <<
std::is_trivial
";
}
При определении конструктора как = default тривиальность класса сохраняется, если она была до этого. В данном случае, это равносильно отсутствию явного упоминания конструктора в определении класса.
Если конструктор по умолчанию определен как = default вне определения класса, всё равно будет считаться, что конструктор предоставлен пользователем, и это тоже делает класс нетривиальным
Сноска на Стандарт по этому поводу (8.4.2/5):
A function is user-provided if it is user-declared and not explicitly
defaulted or deleted on its first declaration.
Различие также будет наблюдаться при попытке создания константного объекта класса конструктором по умолчанию. Например:
const X x;
приведет к ошибке компиляции при определении класса X как:
struct X {
X() = default;
int i;
};
И скомпилируется удачно в случае предоставленного пользователем конструктора по умолчанию:
struct X {
X() {}
int i;
};
Еще один момент, демонстрирующий различие, возникает при использовании пустого списка инициализации при определении объекта. Например:
X x = { };
приведёт к обнулению всех членов класса при = default или отсутствующем явно конструкторе. Если же конструктор будет определён с пустым телом, то такая запись оставит члены класса неинициализированными (мусор).
Комментариев нет:
Отправить комментарий