Что происходит внутри кода конструктора, который компилятор выполняет и предоставляет конструктор по умолчанию? - PullRequest
4 голосов
/ 05 октября 2009

Я хотел бы узнать, что такое работа конструктора, поставляемого компилятором? Этот конструктор выполняет выделение памяти и все необходимое для создания объекта.

Я не задаю этот вопрос с точки зрения инициализации переменной-члена. Я хочу знать, что происходит внутри кода конструктора по умолчанию, который выполняет компилятор и предоставляет конструктор по умолчанию

Ответы [ 4 ]

5 голосов
/ 05 октября 2009

Конструктор по умолчанию - это конструктор, который либо не имеет параметров, либо, если он имеет параметры, все параметры имеют значения по умолчанию.

Если пользовательского конструктора не существует для класса A, и он необходим, компилятор неявно объявляет конструктор по умолчанию без параметров A :: A (). Этот конструктор является встроенным публичным членом своего класса. Компилятор будет неявно определять A :: A (), когда компилятор использует этот конструктор для создания объекта типа A. Конструктор не будет иметь инициализатора конструктора и иметь нулевое тело.

Компилятор сначала неявно определяет неявно объявленные конструкторы базовых классов и нестатические члены-данные класса A, а затем определяет неявно объявленный конструктор A. Не создается конструктор по умолчанию для класса, который имеет какие-либо члены константного или ссылочного типа.

Конструктор класса A тривиален, если выполняются все следующие условия:

* It is implicitly defined
* A has no virtual functions and no virtual base classes
* All the direct base classes of A have trivial constructors
* The classes of all the nonstatic data members of A have trivial constructors

Если что-либо из вышеперечисленного ложно, то конструктор нетривиален.

Член объединения не может иметь тип класса с нетривиальным конструктором.

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

Читать

Конструкторы по умолчанию (только C ++)

2 голосов
/ 05 октября 2009

Конструктор по умолчанию.

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

Если вы не определите каких-либо конструкторов , компилятор сгенерирует для вас конструктор по умолчанию.
Сгенерированный компилятором конструктор по умолчанию делает (в следующем порядке)

  • Вызовите конструктор по умолчанию для всех базовых классов (если есть, но по порядку).
  • Вызовите конструктор по умолчанию для каждого члена (в том порядке, в котором они объявлены в классе).
    • Если член является int / float / char и т. Д., Он не определен.
    • Если элемент является указателем, он не определен.

Конструктор копирования:

Если вы не определили конструктор копирования, компилятор сгенерирует конструктор копирования по умолчанию.
Компилятор сгенерирует конструктор копирования (в следующем порядке)

  • Вызовите конструктор копирования всех базовых классов (если есть, но по порядку).
  • Вызовите конструктор копирования каждого члена (в порядке их объявления в классе).
    • Каждому члену передается соответствующий член копируемого объекта.
    • Примечание для указателей означает, что просто скопируйте значение указателя.
      Вот почему мы получаем проблему поверхностного копирования, когда класс содержит указатель RAW, которым управляет объект.

Хотя не конструктор. Важно отметить, что компилятор также автоматически генерирует оператор присваивания, когда он не определен.
Сгенерированный компилятором оператор присваивания делает (в следующем порядке)

  • Вызовите оператор присваивания каждого базового класса (если есть, но по порядку).
  • Вызовите оператор присваивания каждого члена (в порядке их объявления в классе).
    • Каждому члену передается соответствующий член копируемого объекта.
    • Примечание для указателей означает, что просто скопируйте значение указателя.
      Вот почему мы получаем проблему поверхностного копирования, когда класс содержит указатель RAW, которым управляет объект.

Деструктор по умолчанию:
Большинство людей думают, что деструктор тривиален или нет. Но важно отметить, что на самом деле делает версия по умолчанию (это немного больше, чем ничего).

  • У каждого члена есть свой деструктор (в обратный порядок объявления)
  • Обратите внимание, что int / float / pointers не имеют деструкторов, поэтому ничего явного не делается.
  • Каждый деструктор базового класса вызывается в обратном порядке.

Если вы определяете деструктор, поведение не меняется. Но код, который вы определяете как часть деструктора, выполняется до поведения, определенного выше. Так что в аффекте всегда есть деструктор, просто код - пустой блок.

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

Так что, даже если вы определяете пустой класс. Компилятор всегда сгенерирует для вас четыре метода:

class X: public Z
{
    int a;
    Y   b;
    Z*  c;
};

// Compiler generated methods will look like this:
X::X()
  :Z() // Construct base class.
  //,a?? The default construction of an int does nothing the value is undefined.
  ,b()
  //,c?? The default construction of a pointer does nothing,
{}
X::~X()
{} // Note members are destoyed here
   // ~c:  Does nothing it is a pointer.
   // ~b:  destroyes b via Y::~Y()
   // ~a:  Does nothing as POD has not destructr.
   // ~Z(): Destory base class.
X::(X const& rhs)
    :Z(rhs)
    ,a(rhs.a)
    ,b(rhs.b)
    ,c(rhs.c)
{}
X& operator=(X const& rhs)
{
    Z::operator=(rhs);
    a = rhs.a;
    b = rhs.b;
    c = rhs.c;
    return *this;
}
1 голос
/ 05 октября 2009

что делает компилятор перед созданием законченного объекта

Конструктор по умолчанию, предоставленный компилятором, сделает следующее:

  • Вызовите конструктор по умолчанию для базового класса (если есть базовый класс)
  • Вызовите конструктор по умолчанию для каждого из элементов данных класса (для каждого члена данных, у которого вообще есть конструктор, что означает не примитивные типы) ... и, если исключение выдается одним из них, тогда вызовите деструктор для любых ранее созданных элементов данных.

«конструктор не совсем обычная функция. В частности, он взаимодействует с процедурами управления памятью так, как обычные функции-члены не делают». : Этот тип ответа я ищу .. если кто-нибудь знает больше .. пожалуйста, дайте мне знать? :)

Если вы делаете ...

Something* something = new Something();

... тогда это вызывает «оператор new» (и оператор по умолчанию new выделяет память из кучи), а затем вызывает конструктор для вновь выделенной памяти. Альтернативно, если вы делаете:

Something something;

... затем это выделяет (или резервирует) некоторую память в стеке, а затем вызывает конструктор во вновь выделенной / зарезервированной памяти.

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

0 голосов
/ 05 октября 2009

Вот что я получил из книги Страуструпа

"конструктор не совсем обычная функция. В частности, он взаимодействует с процедурами управления памятью так, как обычные функции-члены не. ": Этот тип ответа я ищу .. если кто-нибудь знает больше .., пожалуйста, дайте мне знать?:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...