#cpp #классы #конструктор #инициализация
Практически всегда в в примерах кода встречал инициализацию полей класса вне тела конструктора: MyClass(): a(1),b(2),c(3) { } а не MyClass() { a = 1; b = 2; c = 3; } Если оба варианта рабочие, в чем практическая польза от инициализации вне тела конструктора?
Ответы
Ответ 1
В первом случае у вас вызываются конструкторы для полей, и тем самым осуществляется инициализация полей.. Во втором случае у вас сначала вызываются конструкторы по умолчанию, и, если инициализаторы полей отсутствуют в их определении, то затем еще вызываются копирующие операторы присваивания, чтобы инициализировать соответствующим образом эти поля, что может быть в конечном итоге очень затратно. Представьте, например, что в конструкторе динамически выделяется память. Тогда затем в копирующем операторе присваивания эта память будет переопределяться. Кроме того может так оказаться, что какой-то член данных вообще не имеет конструктора по умолчанию, а только конструкторы с параметрами. В этом случае второй вариант вообще не будет компилироваться. Рассмотрите простой пример. Данная программа будет успешно компилироваться #includestruct A { int x; A( int x ) : x( x ) {} }; struct B { A a; B() : a( 10 ) {} }; int main() { return 0; } Однако следующая программа компилироваться не будет #include struct A { int x; A( int x ) : x( x ) {} }; struct B { A a; B() { a = 10; } }; int main() { return 0; } так как отсутствует конструктор по умолчанию у класса A, который должен быть вызван до передачи управления управления в тело конструктора B Ответ 2
В порядке вызова. Сначала поля класса инициализируется в списке инциализации (вариант 1). Если списка нет, то компилятор сделает его сам в том порядке, в котором поля объявлены в классе. Потом будет происходить то, что написано в теле конструктора (вариант 2). Для конкретно вашего примера разницы никакой, т.к. у вас используются простые типы данных. Дополнительных накладных расходов нет. Это имеет смысл для классов, которые в качестве полей имеют объекты других классов. Таким способом можно достичь несоздание объекта класса, если при инициализации какого-нибудь его поля произойдёт ошибка. Ну и для объектов других классов могут быть затраты на инициализацию объекта. Поэтому может получиться повторный вызов. Ну и последний аргумент - вариант 1 является хорошей практикой. Думаю, что-то ещё добавят в комментариях и других ответах.
Комментариев нет:
Отправить комментарий