Когда в С++ требуется библиотека #include <new>?
Согласно этой справочной записи для оператора new
(http://www.cplusplus.com/reference/std/new/operator%20new/):
Оператор глобальной динамической памяти функции являются стандартными в стандарте библиотека:
- Все три версии оператора new объявляются в глобальном пространстве имен, не в пространстве имен std.
- Первая и вторая версии неявно объявляются в каждом единица перевода на С++: заголовок не должен быть чтобы они присутствовали.
Мне кажется, что третья версия оператора new (размещение new) неявно объявляется в каждой единицы перевода программы на С++, а заголовок <new>
должен быть включен для ее присутствия. Это правильно?
Если да, то как это получается с использованием компиляторов g++ и MS VС++ Express, я могу скомпилировать код, используя третью версию нового без #include <new>
в моем исходном коде?
Кроме того, эталонная запись библиотеки MSDN Standard С++ для оператора new дает некоторый пример кода для трех форм оператора new, который содержит оператор #include <new>
, однако пример, похоже, компилируется и запускается точно так же для меня, без этого include
// new_op_new.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
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 <new>
- может быть, какой-то примерный код, который не будет компилироваться без #include <new>
?
Спасибо.
Ответы
Ответ 1
Ничто в С++ не предотвращает включение стандартных заголовков других стандартных заголовков. Поэтому, если вы включите какой-либо стандартный заголовок, возможно, косвенно включить все из них. Однако это поведение полностью зависит от реализации, и если вам нужны функции конкретного заголовка, вы всегда должны явно включать его самостоятельно.
Ответ 2
В стандартном стихе С++ 3.7.4.2 говорится: -
Библиотека предоставляет определения по умолчанию для глобальных функций распределения и освобождения. Некоторые функции глобального распределения и освобождения являются сменными (18.6.1). Программа С++ должна предоставлять не более одного определения сменной функции распределения или освобождения. Любое такое определение функции заменяет версию по умолчанию, предоставленную в библиотеке (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();
В этих неявных объявлениях вводится только оператор имен функций new, operator new [], оператор delete, оператор delete []. [Примечание: неявные объявления не содержат имена std, std:: bad_alloc и std:: size_t или любые другие имена, которые библиотека использует для объявления этих имен. Таким образом, выражение newexpression, delete-expression или function, которое ссылается на одну из этих функций без включения заголовка, хорошо сформировано. Однако, ссылаясь на std, std:: bad_alloc и std:: size_t, плохо сформирован, если это имя не было объявлено включением соответствующего заголовка. -end note]
Кроме того, версия std::nothrow
operator new
требует включения заголовка.
Стандарт, хотя и не указывает неявное включение файлов заголовков в другие файлы заголовков. Таким образом, безопасно и портативно следовать стандарту, когда упоминаются имена std::bad_alloc
и т.д.
Ответ 3
Что касается вопроса в заголовке,
" Когда в С++ требуется библиотека #include <new>
?
Ключевое слово new
может использоваться различными способами. Обычное использование не требует включения каких-либо заголовков. Но один из возможных способов использования этого ключевого слова - вызвать конкретную функцию "размещение нового", определенную заголовком <new>
. При таком использовании вам необходимо прямо или косвенно включить заголовок <new>
. Не включайте этот заголовок или любой другой заголовок, если он вам не нужен; не включайте заголовки по умолчанию. С другой стороны, не полагайтесь на конкретную версию заголовка, включая другую: всегда включайте то, что вам нужно, в соответствии со стандартными (или другими) спецификациями того, что они предоставляют.
Что касается вопроса в теле,
" пример, похоже, компилируется и запускается точно так же для меня без этого include?
В С++ стандартным библиотечным заголовкам разрешено включать другие стандартные заголовки библиотек (или материалы, предоставленные другими стандартными заголовками библиотек) по усмотрению реализации.
Ответ 4
Оператор new
, определенный в <new>
header throws bad_alloc
exception (который объявлен в том же заголовке) вместо того, чтобы возвращать NULL, когда выделение памяти невозможно. Заголовок <new>
также определяет
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
который не бросает исключения и не размещает новый вариант. Без <new>
вы получаете только простой старый, возвращающий NULL operator 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();
объявляются в заголовке <new>
. Однако некоторые компиляторы могут сделать их доступными неявно, но это нестандартно, и вы не должны полагаться на него.