Может ли С++ 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;
}
Ответы
Ответ 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
и не сделает программу плохо сформированной.