Когда в C ++ требуется библиотека #include <new>? - PullRequest
41 голосов
/ 07 мая 2010

Согласно этой справочной записи для оператора нового (http://www.cplusplus.com/reference/std/new/operator%20new/):

Глобальный оператор динамического хранения функции являются специальными в стандарте библиотека:

  • Все три версии оператора new объявлены в глобальном пространстве имен, не в пространстве имен std.
  • Первая и вторая версии неявно объявляются в каждом модуль перевода программы на C ++: заголовок не должен быть включены для их присутствия.

Мне кажется, это означает, что третья версия оператора new (размещение нового) неявно объявляется в каждой единице перевода программы на C ++, и для ее присутствия необходимо включить заголовок <new>. Это правильно?

Если так, то как с использованием компиляторов g ++ и MS VC ++ Express кажется, что я могу скомпилировать код, используя третью версию новой версии без #include <new> в моем исходном коде?

Кроме того, в справочной записи библиотеки MSDN Standard C ++ для оператора new приведен пример кода для трех форм оператора new, который содержит оператор #include <new>, однако пример, похоже, компилируется и выполняется для меня точно так же без включения

// 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>?

Спасибо.

Ответы [ 4 ]

13 голосов
/ 07 мая 2010

Стих C ++ Standard 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();

Эти неявные объявления вводят только имена функций, оператор new, оператор new [], оператор delete, оператор delete []. [Примечание: неявные объявления не вводят имена std, std :: bad_alloc и std :: size_t или любые другие имена, которые библиотека использует для объявления этих имен. Таким образом, выражение newexpression, delete-expression или function, которое ссылается на одну из этих функций без включения заголовка, является правильно сформированным. Однако обращение к std, std :: bad_alloc и std :: size_t является некорректным, если имя не было объявлено путем включения соответствующего заголовка. —Конечная записка]

Кроме того, std::nothrow версия operator new требует включения заголовка. Стандарт, однако, не определяет неявное включение файлов заголовков в другие файлы заголовков. Поэтому безопасно и легко следовать стандарту, когда упоминаются имена std::bad_alloc и т. Д.

11 голосов
/ 07 мая 2010

Ничто в C ++ не мешает стандартным заголовкам включать другие стандартные заголовки. Поэтому, если вы включите любой стандартный заголовок, вы можете косвенно включить все из них. Однако это поведение полностью зависит от реализации, и если вам нужны функции конкретного заголовка, вы всегда должны явно включать его самостоятельно.

5 голосов
/ 26 января 2017

По вопросу в названии,

& rdquo; Когда требуется библиотека #include <new> в C ++?

Ключевое слово new можно использовать по-разному. Обычное использование не требует включения каких-либо заголовков. Но один из возможных способов использования этого ключевого слова - вызвать конкретную функцию «размещения нового», определенную заголовком <new>. При таком использовании вам необходимо прямо или косвенно включить заголовок <new>. Не включайте этот заголовок или любой другой заголовок, если он вам не нужен; не включайте заголовки по умолчанию. С другой стороны, не полагайтесь на специфичную для реализации версию заголовка, включая другую: всегда включайте то, что вам нужно, в соответствии со спецификациями стандарта (или других) того, что они предоставляют.

Что касается вопроса в теле,

& rdquo; пример, похоже, компилируется и запускается для меня без включения include?

В заголовках стандартных библиотек C ++ разрешено включать другие заголовки стандартных библиотек (или материал, предоставляемый другими заголовками стандартных библиотек), по усмотрению реализации.

2 голосов
/ 07 мая 2010

Оператор new, определенный в заголовке <new>, генерирует исключение bad_alloc (которое объявлено в том же заголовке) вместо возврата 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>. Однако некоторые компиляторы могут сделать их доступными неявно, но это нестандартно, и вы не должны на это полагаться.

...