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

Когда в С++ требуется библиотека #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>?

Спасибо.

4b9b3361

Ответ 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>. Однако некоторые компиляторы могут сделать их доступными неявно, но это нестандартно, и вы не должны полагаться на него.