Конструктор по умолчанию.
Он имеет нулевые параметры (или все его параметры имеют значения по умолчанию), так что объект может быть построен без каких-либо параметров.
Если вы не определите каких-либо конструкторов , компилятор сгенерирует для вас конструктор по умолчанию.
Сгенерированный компилятором конструктор по умолчанию делает (в следующем порядке)
- Вызовите конструктор по умолчанию для всех базовых классов (если есть, но по порядку).
- Вызовите конструктор по умолчанию для каждого члена (в том порядке, в котором они объявлены в классе).
- Если член является int / float / char и т. Д., Он не определен.
- Если элемент является указателем, он не определен.
Конструктор копирования:
Если вы не определили конструктор копирования, компилятор сгенерирует конструктор копирования по умолчанию.
Компилятор сгенерирует конструктор копирования (в следующем порядке)
- Вызовите конструктор копирования всех базовых классов (если есть, но по порядку).
- Вызовите конструктор копирования каждого члена (в порядке их объявления в классе).
- Каждому члену передается соответствующий член копируемого объекта.
- Примечание для указателей означает, что просто скопируйте значение указателя.
Вот почему мы получаем проблему поверхностного копирования, когда класс содержит указатель RAW, которым управляет объект.
Хотя не конструктор. Важно отметить, что компилятор также автоматически генерирует оператор присваивания, когда он не определен.
Сгенерированный компилятором оператор присваивания делает (в следующем порядке)
- Вызовите оператор присваивания каждого базового класса (если есть, но по порядку).
- Вызовите оператор присваивания каждого члена (в порядке их объявления в классе).
- Каждому члену передается соответствующий член копируемого объекта.
- Примечание для указателей означает, что просто скопируйте значение указателя.
Вот почему мы получаем проблему поверхностного копирования, когда класс содержит указатель RAW, которым управляет объект.
Деструктор по умолчанию:
Большинство людей думают, что деструктор тривиален или нет. Но важно отметить, что на самом деле делает версия по умолчанию (это немного больше, чем ничего).
- У каждого члена есть свой деструктор (в обратный порядок объявления)
- Обратите внимание, что int / float / pointers не имеют деструкторов, поэтому ничего явного не делается.
- Каждый деструктор базового класса вызывается в обратном порядке.
Если вы определяете деструктор, поведение не меняется. Но код, который вы определяете как часть деструктора, выполняется до поведения, определенного выше. Так что в аффекте всегда есть деструктор, просто код - пустой блок.
Примечание. При использовании виртуальных базовых классов есть некоторые особые соображения. Но это другой вопрос.
Так что, даже если вы определяете пустой класс. Компилятор всегда сгенерирует для вас четыре метода:
class X: public Z
{
int a;
Y b;
Z* c;
};
// Compiler generated methods will look like this:
X::X()
:Z() // Construct base class.
//,a?? The default construction of an int does nothing the value is undefined.
,b()
//,c?? The default construction of a pointer does nothing,
{}
X::~X()
{} // Note members are destoyed here
// ~c: Does nothing it is a pointer.
// ~b: destroyes b via Y::~Y()
// ~a: Does nothing as POD has not destructr.
// ~Z(): Destory base class.
X::(X const& rhs)
:Z(rhs)
,a(rhs.a)
,b(rhs.b)
,c(rhs.c)
{}
X& operator=(X const& rhs)
{
Z::operator=(rhs);
a = rhs.a;
b = rhs.b;
c = rhs.c;
return *this;
}