#c #default-constructor
#c #default-constructor
Вопрос:
Если я не определяю конструктор по умолчанию в классе в C или любых других конструкторах, я прочитал, что компилятор создает конструктор по умолчанию для вас. Но я создал тестовый класс, скомпилировал его в ассемблерный код и проверил, чтобы обнаружить, что ничего подобного не создано.
Может ли кто-нибудь пояснить, как создается код для конструктора по умолчанию, или если он создан в первую очередь?
Комментарии:
1. Я подозреваю, решит ли компилятор сгенерировать какой-либо код, зависит от того, как выглядит ваш класс. Если у вас есть члены класса, у которых есть конструкторы, которые необходимо вызвать, у компилятора есть причина для генерации кода. Если у вас есть члены класса, которые являются только базовыми типами (например, int), конструктору по умолчанию нечего делать, поэтому компилятору не нужно писать какой-либо код…
Ответ №1:
Конструктор по умолчанию создается, если вам это нужно, например:
class Foo {
std::string s;
};
...
Foo f;
12.1:
Конструктор по умолчанию (12.1), конструктор копирования и оператор присваивания копирования (12.8), а также деструктор (12.4) являются специальными функциями-членами. Реализация будет неявно объявлять эти функции-члены для типа класса, когда программа явно не объявляет их, за исключением случаев, отмеченных в 12.1. Реализация неявно определит их, если они будут использоваться, как указано в 12.1, 12.4 и 12.8.
Кроме того, если вашему классу не требуется ничего выполнять в конструкторе, компилятор может предпочесть не генерировать код, хотя по стандарту конструктор должен существовать.
Комментарии:
1. Конструктор по умолчанию создается всегда. Однако он является встроенным, и если он тривиален, для него не будет сгенерирован машинный код. (В дополнение к добавлению класса с нетривиальным конструктором, вы можете просто добавить виртуальную функцию, чтобы сделать ее нетривиальной.)
2. @Джеймс Канзе: Он всегда объявляется . Он определяется только в том случае, если вы создаете объект, используя его.
3. ДА. Мой выбор слова «созданный» был немного расплывчатым, поскольку существует два «создания»: создание объявления и создание определения. Первое происходит всегда, второе только по мере необходимости.
Ответ №2:
C != Сборка.
Ассемблер — это (один из возможных) выходных данных для скомпилированной программы на C , которая может включать или не включать определенные оптимизации, которые могли бы исключить вызов возможно пустого конструктора.
Другими словами, язык говорит, что есть конструктор по умолчанию, но он описывает только поведение, а не реализацию. Если кажется, что реализации не нужно генерировать код, то это и не обязательно.
Ответ №3:
Вот что говорится в стандарте C 03:
§12.1/5:
Конструктор по умолчанию для класса X — это конструктор класса X, который может быть вызван без аргумента. Если для класса X нет конструктора, объявленного пользователем, неявно объявляется конструктор по умолчанию. Неявно объявленный конструктор по умолчанию является встроенным открытым членом своего класса. Конструктор тривиален, если это неявно объявленный конструктор по умолчанию и если:
- его класс не имеет виртуальных функций (10.3) и виртуальных базовых классов (10.1), и
- все прямые базовые классы его класса имеют тривиальные конструкторы, и
- для всех нестатических элементов данных его класса, которые имеют тип class (или их массив), каждый такой класс имеет тривиальный конструктор.
§12.1/6:
В противном случае конструктор нетривиален.
§12.1/7:
Неявно объявленный конструктор по умолчанию для класса неявно определяется, когда он используется для создания объекта его типа class (1.8). Неявно определенный конструктор по умолчанию выполняет набор инициализаций класса, которые были бы выполнены пользовательским конструктором по умолчанию для этого класса с пустым списком mem-initializer-list (12.6.2) и пустым телом функции. Если этот пользовательский конструктор по умолчанию был бы неверно сформирован, программа неверно сформирована. Прежде чем неявно объявленный конструктор по умолчанию для класса будет неявно определен, все неявно объявленные конструкторы по умолчанию для его базовых классов и его нестатических элементов данных должны быть неявно определены. [Примечание: неявно объявленный конструктор по умолчанию имеет спецификацию исключения (15.4).]
Подразумевается, что для классов с неявно объявленными, но неявно определенными конструкторами по умолчанию или для классов с неявно определенными тривиальными конструкторами по умолчанию генерация кода может не потребоваться.
Ответ №4:
Вы хотели спросить, действительно ли ваш компилятор выдает код для конструктора по умолчанию?
Это зависит от оптимизации. Большинство современных компиляторов будут выдавать последовательность кода конструктора по умолчанию при использовании с -O0, но оптимизируют ее, если она не используется, и вы используете -O2 или выше.
Комментарии:
1. Или, возможно, просто встроить конструктор не совсем тривиально.