Стандарты программирования на С++. 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);

> }

>};

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