Согласно этой ссылке для оператора, нового (http://www.cplusplus.com/reference/std/new/operator%20new/):
Глобальные функции оператора динамической памяти являются особенными в стандартной библиотеке:
- Все три версии нового оператора объявляются в глобальном пространстве имен, не в пространстве имен станд.
- Первые и вторые версии неявно объявляются в каждой единице перевода программы C++: заголовок не должен быть включен, чтобы они присутствовали.
Это, кажется, мне подразумевает, что третья версия нового оператора (новое размещение) неявно не объявляется в каждой единице перевода программы C++ и заголовка
действительно должен быть включен, чтобы это присутствовало. Это корректно?
Если так, как получается, что с помощью и g ++ и MS VC ++ компиляторы Экспресса, кажется, что я могу скомпилировать код с помощью третьей версии новых без #include
в моем исходном коде?
Кроме того, Стандарт MSDN, который запись Справочного руководства по библиотеке C++ на новом операторе дает некоторому примеру кода для трех форм оператора, нового, который содержит #include
оператор, однако пример, кажется, компилирует и работает все равно за мной без этого, включают?
// new_op_new.cpp
// compile with: /EHsc
#include
#include
using namespace std;
class MyClass
{
public:
MyClass( )
{
cout << "Construction MyClass." << this << endl;
};
~MyClass( )
{
imember = 0; cout << "Destructing MyClass." << this << endl;
};
int imember;
};
int main( )
{
// The first form of new delete
MyClass* fPtr = new MyClass;
delete fPtr;
// The second form of new delete
char x[sizeof( MyClass )];
MyClass* fPtr2 = new( &x[0] ) MyClass;
fPtr2 -> ~MyClass();
cout << "The address of x[0] is : " << ( void* )&x[0] << endl;
// The third form of new delete
MyClass* fPtr3 = new( nothrow ) MyClass;
delete fPtr3;
}
Мог любой проливать некоторый свет на это и когда и почему Вы, возможно, должны были бы #include
- возможно, некоторый пример кода, который не скомпилирует без #include
?
Спасибо.
Ничто в C ++ не препятствует включению в стандартные заголовки других стандартных заголовков. Поэтому, если вы включаете любой стандартный заголовок , вы, возможно, косвенно можете включить все из них. Однако это поведение полностью зависит от реализации, и если вам нужны функции определенного заголовка, вы всегда должны явно включать его самостоятельно.
Стих стандарта C ++ 3.7.4.2 говорит: -
Библиотека предоставляет по умолчанию определения для глобальных функций распределения и освобождения. Некоторые функции глобального распределения и освобождения можно заменить (18.6.1). Программа на C ++ должна предоставлять не более одного определения заменяемой функции выделения или освобождения. Любое такое определение функции заменяет версию по умолчанию, представленную в библиотеке (17.6.3.6). Следующие функции распределения и освобождения (18.6) неявно объявляются в глобальной области видимости в каждой единице трансляции программы.
void* operator new(std::size_t) throw(std::bad_alloc);
void* operator new[](std::size_t) throw std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
Эти неявные объявления вводят только имена функций: operator new, operator new [], operator delete, operator delete []. [Примечание: неявные объявления не вводят имена std, std :: bad_alloc и std :: size_t или любые другие имена, которые библиотека использует для объявления этих имен. Таким образом, новое выражение, выражение-удаление или вызов функции, которые ссылаются на одну из этих функций без включения заголовка, являются правильно сформированными.Однако ссылка на std, std :: bad_alloc и std :: size_t неверна, если имя не было объявлено с включением соответствующего заголовка. —End note]
Кроме того, версия std :: nothrow
оператора new
требует включения заголовка.
Стандарт, хотя и не определяет неявное включение файлов заголовков в другие файлы заголовков. Таким образом, при упоминании имен std :: bad_alloc
и т. Д. Соблюдение стандарта безопасно и переносимо.
Оператор new
, определенный в
заголовке, выдает исключение bad_alloc
(которое объявлено в том же заголовке) вместо возврата NULL, если выделение памяти не выполнено. возможный. Заголовок
также определяет вариант
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
, который не генерирует исключения и не размещает новый вариант. Без . Все три перегрузки оператора:
вы получите только обычный старый, возвращающий NULL оператор new
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new (std::size_t size, void* ptr) throw();
объявлены в заголовке
. Однако некоторые компиляторы могут сделать их доступными неявно, но это нестандартно, и вам не следует полагаться на это.