Может ли C ++ 0x по-прежнему явно распределяться с помощью глобального оператора new? - PullRequest
17 голосов
/ 27 сентября 2010

Википедия сообщает:

Невозможно выделить тип с помощью оператора new:

struct NonNewable {
    void *operator new(std::size_t) = delete;
};

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

Удаление оператора new аналогично созданиюон частный в текущем C ++, но явно не использует глобальный оператор new, который избегает поиска по классам, все еще действительный C ++ 0x?

NonNewable *p = ::new NonNewable();
// neither non-portable nor trickery, though perhaps not widely known

Я что-то пропустил в черновике?


Для ясности, это действительно C ++ 03 и отлично работает :

struct NonNewable {
private:
  void *operator new(std::size_t);  // not defined
};

int main() {
  // ignore the leaks, it's just an example

  void *mem = operator new(sizeof(NonNewable));
  NonNewable *p = ::new(mem) NonNewable();

  p = ::new NonNewable();

  return 0;
}

1 Ответ

6 голосов
/ 27 сентября 2010

Я верю, что вы правы, а Википедия не права.Проект стандарта C ++ 0x описывает «удаленные функции» (8.4p10) как функции, которые не могут быть использованы каким-либо образом (или программа неправильно сформирована).Они не играют никакой роли в области видимости или имени, отличной от обычных функций.И соответствующие параграфы, касающиеся новых выражений, остались прежними:

[5.3.4p8] Новое выражение получает хранилище для объекта, вызывая функцию выделения (3.7.4.1)....

[5.3.4p9] Если выражение new начинается с унарного оператора ::, имя функции распределения ищется в глобальной области видимости.В противном случае, если выделенный тип является типом класса T или его массивом, имя функции распределения ищется в области действия T. Если при этом поиске не удается найти имя или если выделенный тип не является типом класса, распределениеимя функции ищется в глобальной области видимости.

Так что да, выражение ::new NonNewable [или ::new(mem) NonNewable] выберет перегрузку ::operator new, игнорируя функцию NonNewable::operator new ине сделает программу плохо сформированной.

...