Конструктор по умолчанию в C ++
-
27-10-2019 - |
Вопрос
Мне было просто любопытно по этому вопросу, но не смог найти ответ в Интернете.
Предположим, у нас есть простой заголовок:
// SimpleHeader.h
class SimpleClass
{
int i;
}
Как мы знаем, конструктор по умолчанию автоматически генерируется для этого класса.
Теперь у меня еще 2 файла:
// First.cpp
#include <SimpleHeader.h>
// ...
SimpleClass a;
// ...
а также
//Second.cpp
#include <SimpleHeader.h>
// ...
SimpleClass b;
// ...
Будут ли First.obj и Second.obj содержать код для класса
Решение
Из стандарта: если вы не пишете каких -либо конструкторов, вам будет предоставлен конструктор по умолчанию, и этот конструктор по умолчанию определяется встроенным и эквивалентным пустому конструктору T::T() {}
.
Я почти уверен, что [отредактировать] ваш вставленный конструктор на самом деле вообще не приведет к какому -либо машинному коду.
Другие советы
Да, предположительно компилятор должен генерировать код в обоих объектных файлах, если в конечном итоге они не были связаны вместе. Затем линкер использует одно правило определения, чтобы выбрать одну версию, и выбросить другую, когда вы связываете два файла объекта вместе в исполняемый двоичный файл.
Прежде всего, это, безусловно, зависит от компилятора и многих других обстоятельств.
Вот 3 общих сценария.
Конструктор по умолчанию генерируется и включен в каждый из ваших первых файлов.
Конструктор вставлен везде, где вы создаете объект (обычно только для простых конструкторов, где компилятор может просто нулевать память)
Нет необходимости генерировать/вызвать конструктор по умолчанию. Это может произойти, если вы объявите объект в области масштаба файла, и объект просто нуждается в нулевом нулевом виде памяти - компилятор может просто поместить объект в специальную область, которая нулевая инициализирована при запуске программы - и не вызывает вызов конструктора по умолчанию.
Конструктор по умолчанию - это не больше, чем распределение пространства для объекта. Поскольку на стадии загрузчика уже не выделяется динамическая память, и больше кода не требуется.
Более интересным будет то, что произойдет, если бы вы реализовали сложный конструктор и динамически распределяют объекты.
В этом случае оба файла OBJ будут иметь код конструктора.
Ни один. В C и C ++ вы можете объявить что -то много раз, говоря, что для этой функции есть код, но это где -то еще. Вы можете определить только один раз, и в том месте, где вы его определили, вот где код генерируется, в этом файле OBJ. Итак, у вас есть три файла .cpp и один заголовок, первый файл, определяющий класс, два других делают его объекты. Файлы OBJ для двух других файлов не будут содержать какого -либо кода для класса, лишь некоторая информация, которая достаточно для линкера для размещения вызовов в код, является определяющим файлом OBJ.
Если вы определите класс в двух местах, путем неявного размещения определений методов в заголовок, включенного в несколько файлов, линкер не возражает, потому что определения «одинаковы», они просто появляются в каждом OBJ изначально, и Окончательное приложение будет включать только одну из единиц, сгенерированных по умолчанию.
Вы всегда можете сделать столько экземпляров класса, сколько захотите, и код метода никогда не копируется. Он существует в одном месте для всех различных файлов, функций и для того, чтобы использовать и производить объекты этого класса.
Некоторые конструкторы по умолчанию могут быть умными и нуждаются в некотором коде, некоторые для структурных структур, например, могут быть полностью оптимизированы и не нуждаются в каком -либо коде. Это всегда так, что создание большего количества экземпляров не копирует какие -либо функции, включая конструкторы.