2010-09-27 1 views
17

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

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

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

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

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

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

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


Чтобы было ясно, это справедливо C++ 03 и works fine:

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

FYI, если вы проверяете: цитируемый текст был удален из статьи в Википедии. – 2010-10-01 10:52:58

ответ

6

Я считаю, что вы правы и википедии неправильно. В черновом стандарте C++ 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, и не будет делать программа плохо сформированным.

Смежные вопросы