Стандарты программирования на С++. 101 правило и рекомендация | страница 82
>class С {
> // ...
> // Скрывает три стандартных вида оператора new
> static void* operator new(size_t, MemoryPool&);
>};
Теперь, если кто-то попытается написать выражение с обычным стандартным >new
С, компилятор сообщит о том, что он не в состоянии найти обычный старый оператор >new
. Объявление перегрузки >C::operator new
с параметром типа >MemoryPool
скрывает все остальные перегрузки, включая знакомые встроенные глобальные версии, которые все мы знаем и любим:
>void* operator new(std::size_t); // Обычный
>void* operator new(std::size_t,
> std::nothrow_t) throw(); // He генерирующий исключений
>void* operator new(std::size_t,
> void*); // Размещающий
В качестве другого варианта событий предположим, что ваш класс предоставляет некоторую специфичную для данного класса версию оператора >new
— одну из трех. В таком случае это объявление также скроет остальные две версии:
>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);
> }
>};
Рассмотренная рекомендация применима также к версиям операторов для массивов —