48. В конструкторах предпочитайте инициализацию присваиванию
48. В конструкторах предпочитайте инициализацию присваиванию
Резюме
В конструкторах использование инициализации вместо присваивания для установки значений переменных-членов предохраняет от ненужной работы времени выполнения при том же объеме вводимого исходного текста.
Обсуждение
Конструкторы генерируют скрытый код инициализации. Рассмотрим следующий код:
class A {
string s1_, s2_;
public:
A() { s1_ = "Hello, "; s2_ = "world"; }
};
В действительности сгенерированный код конструктора выглядит так, как если бы вы написали:
А() : s1_(), s2_() { s1_ = "Hello, "; s2_ = "world"; }
To есть объекты, не инициализированные вами явно, автоматически инициализируются с использованием их конструкторов по умолчанию, после чего выполняется присваивание значений с использованием их операторов присваивания. Чаще всего операторы присваивания нетривиальных объектов выполняют немного больше работы, чем конструкторы, поскольку работают с уже созданными объектами.
Таким образом, инициализация переменных-членов в списке инициализации дает код, лучше выражающий ваши намерения и обычно более быстрый и меньшего размера:
А() : s1_("Hello, "), s2_("world ") { }
Эта методика не является преждевременной оптимизацией; это — избежание преждевременной пессимизации (см. рекомендацию 9).
Исключения
Всегда выполняйте захват неуправляемого ресурса (например, выделение памяти оператором new, результат которого не передается немедленно конструктору интеллектуального указателя) в теле конструктора, а не в списке инициализации (см. [Sutter02]). Конечно, лучше всего вообще не использовать таких небезопасных и не имеющих владельца ресурсов (см. рекомендацию 13).
Ссылки
[Dewhurst03] §51, §59 • [Keffer95] pp.13-14 • [Meyers97] §12 • [Murray93] §2.1.31 • [Sutter00] §8, §47 • [Sutter02] §18
Больше книг — больше знаний!
Заберите 20% скидку на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ