Подтвердить что ты не робот

Использование конструктора в С++

Это очень тривиальный вопрос относительно использования конструктора в С++. Я представлю в форме диалога с интервью (его трудно было представить в любых других формах)

интервьюер -, что такое конструктор?
Конструктор me - - это специальные функции, которые гарантируют, что все объекты будут инициализированы до их использования.

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

интервьюер -, что означает, что инициализация выполняется в списке инициализаторов, а не внутри конструктора. Но вы сказали, что конструктор инициализирует объект! Не так ли? Вы хотите ответить на мой первый вопрос.
me - Я думаю, что конструктор выполняет назначение, он вызывает оператор присваивания на уже инициализированных объектах-членах.

Итак, мой вопрос для вас может быть

как работает список инициализаций?

что находится между начальным адресом функции и начальными скобками [{]?

или просто ответьте мне, как убедить моего интервьюера.

4b9b3361

Ответ 1

Ты слишком задумываешься о нем и позволяешь интервьюеру смутить тебя.

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

Ответ 2

С технической точки зрения, ваша интерпретация точна. Никакие члены не могут быть инициализированы внутри тела ctor; только в ctor-initializer. Любой членский доступ в теле ctor может быть только назначением.

Все члены "инициализируются" до ввода тела ctor.

Однако, говоря более широко, поскольку тело всегда следует за инициализатором, он сказал, что — как единое целое; объект инициализируется после завершения конструктора... включая тело.

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

Ответ 3

Основные сведения о списке инициализации - эффективность и читаемость кода.

Часть читаемости не требует пояснений, потому что вы точно знаете, где искать, где значения инициализируются. Экономия эффективности заключается в том, что если вы назначили им значения внутри кода конструктора, то они будут назначены дважды: во-первых, когда объект будет создан, им будут назначены значения, предоставленные этим конструктором по умолчанию для данного типа данных, тогда они будут присваивается новое значение в вашем конструкторе объектов. Список инициализации просто гарантирует, что они инициализируются со значением, которое вы указали для начала.

например, вот пример списка инициализации, который я использовал в реализации Doubly Linked List:

template <typename T>
LinkedList<T>::LinkedList()
: size(0)
, pHead(NULL)
, pTail(NULL)
{
}

В то время как менее эффективная версия, где размер, pHead и pTail назначается дважды, показан ниже:

template <typename T>
LinkedList<T>::LinkedList()
{
    size = 0;
    pHead = NULL;
    pTail = NULL;
}

Ответ 4

По существу, вы правы, но инициализатор элемента не должен рассматриваться отдельно от конструктора. Инициализатор является частью конструктора и вызывается перед основным телом конструктора.

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

int var1; // declares/defines var of type int

int var2 = 0; // declares/defines a var of type int and initializes it to 0

Инициализатор устанавливает переменную с начальным значением, когда она определена, но считается, что она определена до инициализатора.

int x = 5;
int y = 5;

int main()
{
    int x = x; // x is undefined here not 5 because x refers to itself
    int y[y];
    int size = sizeof(y)/sizeof(int); // size is 5 (y[5]) since y isn't defined until after the enclosing bracket so y referred to the global y in the declaration.
}

Существуют некоторые переменные, которые должны инициализироваться. Константы и ссылки.

То же самое с конструкторами. Точка, в которой члены были определены, находится прямо перед телом. Это порядок, когда члены и базы определяются при вызове конструктора.

  • виртуальные базовые классы
  • базовый класс
  • - в том порядке, в котором они были объявлены
  • выполняется тёрное тело

После выхода из тела конструктора все инициализируется.

Если вы не используете инициализатор, вы можете предположить, что он уже определен при вводе тела ctor, но вы не можете предположить, что он имеет какое-то особое значение. Опять же, константы и ссылки должны быть инициализированы в инициализаторе члена.

Ответ 5

Список инициализаторов является частью конструктора. Каждый конструктор имеет свой собственный.