Чтение онлайн

на главную - закладки

Жанры

Стандарты программирования на С++. 101 правило и рекомендация

Александреску Андрей

Шрифт:

class С {

 // ...

 // Скрывает две другие стандартные версии оператора new

 static void* operator new(size_t, void*);

};

Предпочтительно, чтобы у класса С в его область видимости были явно внесены все три стандартные версии оператора

new
. Обычно все они должны иметь одну и ту же видимость. (Видимость для отдельных версий может быть сделана закрытой, если вы хотите явно запретить один из вариантов оператора
new
, однако
цель данной рекомендации — напомнить, чтобы вы не скрыли эти версии непреднамеренно.)

Заметим, что вы должны всегда избегать сокрытия размещающего

new
, поскольку он интенсивно используется контейнерами стандартной библиотеки.

Все, что осталось упомянуть, — это то, что внесение оператора

new
в область видимости может быть сделано двумя различными способами в двух разных ситуациях. Если базовый класс вашего класса также определяет оператор
new
, все, что вам надо, — "раскрыть" оператор
new
:

class С : public B { // ...

public:

 using B::operator new;

};

В противном случае, если не имеется базового класса или в нем не определен оператор

new
, вы должны написать короткую пересылающую функцию (поскольку нельзя использовать using для внесения имен из глобальной области видимости):

class C { // ...

public:

 static void* operator new(std::size_t s) {

return ::operator new(s);

 }

 static void* operator new(std::size_t s,

std::nothrow_t nt) throw {

return ::operator new(s, nt);

 }

 static void* operator new(std::size_t s, void* p) {

return ::operator new(s, p);

 }

};

Рассмотренная рекомендация применима также к версиям операторов для массивов —

operator new[]
.

Избегайте вызова версии

new(nothrow)
в вашем коде, но тем не менее обеспечьте и ее, чтобы пользователи вашего класса не оказались в какой-то момент неприятно удивлены.

Ссылки

[Dewhurst03] §60 • [Sutter04] §22-23

Конструкторы, деструкторы и копирование

Если стандарт привел вас к обрыву, это еще не значит, что вы должны прыгнуть с него.

— Норман Даймонд (Norman Diamond)

О Большой Четверке специальных функций было сказано достаточно, чтобы вы не удивлялись тому, что им посвящен отдельный раздел. Здесь собраны знания и практика, связанные с конструкторами по умолчанию, копирующими конструкторами, копирующим присваиванием и деструкторами.

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

хотя бы полшанса — он тут же напишет эти функции за вас. Еще одна причина состоит в том, что С++ по умолчанию рассматривает классы как типы-значения, но далеко не все типы именно таковы (см. рекомендацию 32). Надо отчетливо понимать, когда следует писать (или запрещать) эти специальные функции явно, и следовать правилам и рекомендациям из этого раздела — это поможет вам в написании корректного, расширяемого и безопасного кода.

В этом разделе мы считаем наиболее значимой рекомендацию 51 — "Деструкторы, функции освобождения ресурсов и обмена не ошибаются".

47. Определяйте и инициализируйте переменные-члены в одном порядке

Резюме

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

Обсуждение

Рассмотрим следующий код:

class Employee {

 string email_, firstName_, lastName_;

public:

 Employee( const char* firstName, const char* lastName ) :

firstName_(firstName), lastName_(lastName),

email_(firstName_+"."+lastName_+"@acme.com") {}

};

Этот код содержит ошибку, столь же неприятную, сколь и трудно обнаруживаемую. Поскольку член

email_
объявлен в определении класса до
first_
и
last_
, он будет инициализирован первым и будет пытаться использовать еще не инициализированные поля. Более того, если определение конструктора находится в отдельном файле, то выявить такое удаленное влияние порядка объявления переменных-членов класса на корректность конструктора окажется еще труднее.

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

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

Многие компиляторы (но не все) выдают предупреждение при нарушении этого правила.

Ссылки

[Cline99] §22.03-1] • [Dewhurst03] §52-53 • [Koenig97] §4 • [Lakos96] §10.3.5 • [Meyers97] §13 • [Murray93] §2.1.3 • [Sutter00] §47

48. В конструкторах предпочитайте инициализацию присваиванию

Резюме

В конструкторах использование инициализации вместо присваивания для установки значений переменных-членов предохраняет от ненужной работы времени выполнения при том же объеме вводимого исходного текста.

Поделиться:
Популярные книги

Как я строил магическую империю 4

Зубов Константин
4. Как я строил магическую империю
Фантастика:
боевая фантастика
постапокалипсис
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 4

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Попаданка 3

Ахминеева Нина
3. Двойная звезда
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Попаданка 3

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

Призыватель нулевого ранга. Том 3

Дубов Дмитрий
3. Эпоха Гардара
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга. Том 3

На границе империй. Том 10. Часть 5

INDIGO
23. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 5

Адвокат

Константинов Андрей Дмитриевич
1. Бандитский Петербург
Детективы:
боевики
8.00
рейтинг книги
Адвокат

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

О, Путник!

Арбеков Александр Анатольевич
1. Квинтет. Миры
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
О, Путник!

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Бестужев. Служба Государевой Безопасности. Книга четвертая

Измайлов Сергей
4. Граф Бестужев
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга четвертая

Локки 5. Потомок бога

Решетов Евгений Валерьевич
5. Локки
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Локки 5. Потомок бога

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4