Ответ 1
Термины default и implicit, говоря о конструкторе, имеют следующее значение:
-
конструктор по умолчанию - это конструктор, который может быть вызван без аргументов. Он либо не принимает аргументов, либо имеет значения по умолчанию для каждого из принятых аргументов.
-
неявный конструктор - это термин, обычно используемый для разговора о двух разных понятиях на языке,
-
неявно объявленный конструктор, который является конструктором по умолчанию или копией, который будет объявлен для всех пользовательских классов, если не указан какой-либо пользовательский конструктор (по умолчанию), или нет конструктора копирования (копия). То есть класс без конструкторов, объявленных пользователем, имеет один конструктор по умолчанию, неявно объявленный.
-
неявно определенный конструктор - это неявно объявленный конструктор, который используется (odr-used 1 в языке и для которого компилятор предоставит определение.
struct test { test(int i = 0) { } // test(test const&) implicitly declared here }; struct test2 { }; // implicitly declared: test2(), test2(test2 const&) int main() { test t; test copy(t); // causes *definition* of the implicitly // declared copy constructor test2 t2; // causes *definition* of test2::test2() test2 copy2(t2); // causes *definition* of test2::test2(test2 const&) }
-
В простых терминах конструктор по умолчанию используется, если его можно вызвать без аргументов. Конструктор неявный (объявлен/определен), если он не предоставлен пользователем, но объявлен/определен.
В зависимости от конкретных случаев:
Test t1;
Использует конструктор по умолчанию Test(int = 0)
, который не является неявным.
Test t2();
Это странная причуда языка, она объявляет функцию, которая не принимает аргументов и возвращает объект Test
.
Test t3 = 3;
Это называется копией-инициализацией и эквивалентно составу неявного преобразования * от 3
до Test
и скопируйте построение t3
из результата преобразования. Это будет использовать конструктор Test(int)
для преобразования, а затем неявно определенный (и объявленный) экземпляр копии. Примечание: компилятор может оптимизировать копию, но должен убедиться, что конструктор копирования доступен (спецификаторы доступа) и может быть определен.
Test t4(4);
Использует конструктор Test(int)
, который в этом случае не действует как конструктор по умолчанию.
Test t5 = Test(5);
Эквивалентен случаю Test t3 = 3
, с той лишь разницей, что преобразование из 5
в Test
является явным в этом случае. В этом примере это не имеет значения, но если конструктор был помечен как explicit
, эта строка будет компилироваться, а случай t3
завершится с ошибкой.
*) Еще одно использование неявного, в данном случае ссылающегося на то, что преобразование из 3
в Test
явно не запрашивается в коде. Сравните это с t5
, где программа-программист явно запрашивает преобразование: Test(5)
.