Конструктор по умолчанию - это конструктор, который либо не имеет параметров, либо все параметры которого имеют значения по умолчанию.
Если для класса A конструктор не задан пользователем, компилятор неявно объявляет конструктор без параметров по умолчанию A::A(). Этот конструктор является inline public членом своего класса. Компилятор будет неявно определять A::A(), когда компилятор использует этот конструктор для создания объекта типа A. Конструктор не будет иметь инициализатора конструктора и нулевого тела.
Компилятор сначала неявно определяет неявно объявленные конструкторы базовых классов и нестатические элементы данных класса A, прежде чем определять неявно объявленный конструктор A. Это утверждение означает, что, когда компилятор должен создать определение для неявно объявленного конструктора по умолчанию, перед определением текущего конструктора компилятор должен убедиться, что все члены могут быть сконструированы по умолчанию, и для этого ему может потребоваться неявно определить любой неявно объявленный конструктор по умолчанию конструктор элементов.
Кратко One Definition Rule(ODR) - Правило одного определения - В любой единице трансляции(читай файл) допускается только одно определение любой переменной, функции, типа класса, типа перечисления, концепта (начиная с C++20) или шаблона (некоторые из них могут иметь несколько объявлений, но допускается только одно определение).
Подробно: [One Definition Rule - odr]
Пример #1: Создание неявных конструкторов
class A { int x; };
class B { A a; }; // [1]
int main() {
B b; // [2]
}
Определение переменной b в [2] является использованием odr-неявно объявленного конструктора для B, но прежде чем компилятор неявно определит B::B(), поскольку у В есть член типа A, объявленный в [1], ему необходимо неявно определить A::A(). Причина в том, что B::B() будет odr-использовать A::A() в своем списке инициализации.
Конструктор класса A является тривиальным(trivial), только если верно все следующее:
- Он неявно объявлен или начиная с C++11 явно объявлен default
- A не имеет виртуальных функций и виртуальных базовых классов.
- Все прямые базовые классы A имеют тривиальные конструкторы.
- Классы всех нестатических элементов данных A имеют тривиальные конструкторы.
Член union не может принадлежать к типу класса, который имеет нетривиальный конструктор.
Как и все функции, конструктор может иметь аргументы по умолчанию. Они используются для инициализации объектов-членов. Если заданы значения по умолчанию, конечные аргументы могут быть опущены в списке выражений конструктора. Обратите внимание, что если у конструктора есть какие-либо аргументы, которые не имеют значений по умолчанию, это не конструктор по умолчанию. В следующем примере определяется класс с одним конструктором и двумя конструкторами по умолчанию.
Пример #2: Конструкторы
class X {
public:
X(); // Конструктор по умолчанию без аргументов
X(int = 0); // Конструктор по умолчанию с аргументами имеющими значение по умолчанию
X(int, int , int = 0); // Конструктор
};