Подтвердить что ты не робот

Может ли С++ 0x по-прежнему явно выделять глобальный оператор new?

Wikipedia:

Тип можно сделать невозможным для нового оператора:

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

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

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

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

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


Чтобы быть понятным, это действительно С++ 03 и отлично работает:

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

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

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

  p = ::new NonNewable();

  return 0;
}
4b9b3361

Ответ 1

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

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

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

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