Конструктор по умолчанию в C ++ - PullRequest
7 голосов
/ 08 сентября 2011

Мне просто было любопытно задать вопрос, но я не смог найти ответ в Интернете.

Предположим, у нас есть простой заголовок:

// 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 содержатькод для класса

Ответы [ 5 ]

4 голосов
/ 08 сентября 2011

Из стандарта: если вы не пишете никаких конструкторов, вам будет предоставлен конструктор по умолчанию, и этот конструктор по умолчанию будет определен внутри строки и эквивалентен пустому конструктору T::T() {}.

Я почти уверен, что [править] ваш встроенный конструктор вообще не приведет ни к какому машинному коду.

3 голосов
/ 08 сентября 2011

Прежде всего, это, безусловно, зависит от компилятора и многих других обстоятельств.

Вот 3 распространенных сценария.

  1. Конструктор по умолчанию генерируется и включается вкаждый из ваших объектных файлов First.obj и Second.obj, но когда вы связываете их вместе для создания исполняемого файла, используется и включается только один из них.

  2. Конструктор является встроеннымвезде, где вы создаете объект (обычно только для простых конструкторов, где компилятор может просто обнулить память)

  3. Нет необходимости генерировать / вызывать конструктор по умолчанию.Это может произойти, если вы объявляете объект в области видимости файла, и объекту просто нужно инициализировать ноль его памяти - компилятор может просто поместить объект в специальную область, инициализируемую нулем при запуске программы, - и вообще не вызывать конструктор по умолчанию.

3 голосов
/ 08 сентября 2011

Да, предположительно, компилятор должен сгенерировать код в обоих объектных файлах на случай, если они в конце концов не будут связаны друг с другом. Затем компоновщик использует одно правило определения, чтобы выбрать одну версию и выбросить другую, когда вы связываете два объектных файла вместе в исполняемый двоичный файл.

0 голосов
/ 08 сентября 2011

Ни. В C и C ++ вы можете объявлять что-то много раз, говоря, что есть код для этой функции, но это где-то еще. Вы можете определить только один раз, и в том месте, где вы его определили, именно там генерируется код, в этом файле obj. Итак, у вас есть три файла .cpp и один заголовок: первый файл определяет класс, а два других составляют его объекты. Файлы obj для двух других файлов не будут содержать никакого кода для класса, только некоторая информация, достаточная для того, чтобы компоновщик вставил вызовы к коду, является целью определяющего файла.

Если вы определяете класс в двух местах, неявно помещая определения методов в заголовок, включенный в несколько файлов, компоновщик не будет возражать, поскольку определения «одинаковы», они просто появляются в каждом объекте изначально и окончательное приложение будет включать только одну из сгенерированных функций по умолчанию.

Вы всегда можете создать столько экземпляров класса, сколько захотите, и код метода никогда не копируется. Он существует в одном месте для всех различных файлов, функций и т. Д., Чтобы использовать и создавать объекты этого класса.

Некоторые конструкторы по умолчанию могут быть умными и требовать некоторого кода, некоторые для структур POD, например, могут быть полностью оптимизированы и не нуждаются в каком-либо коде. Однако всегда случается так, что создание большего количества экземпляров не копирует никакие функции, включая конструкторы.

0 голосов
/ 08 сентября 2011

Конструктор по умолчанию не более чем выделение места для объекта. поскольку это не динамические переменные, на этапе загрузки уже выделена память, и больше не требуется код.

Более интересным было бы то, что произошло бы, если бы вы реализовали сложный конструктор и динамически распределяли объекты.
В этом случае оба файла obj будут иметь код конструктора.

...