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

Согласно этой ссылке для оператора, нового (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 ?

Спасибо.

44
задан Paul Caheny 7 May 2010 в 12:09
поделиться

3 ответа

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

11
ответ дан 26 November 2019 в 22:20
поделиться

Стих стандарта 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 и т. Д. Соблюдение стандарта безопасно и переносимо.

14
ответ дан 26 November 2019 в 22:20
поделиться

Оператор 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();

объявлены в заголовке . Однако некоторые компиляторы могут сделать их доступными неявно, но это нестандартно, и вам не следует полагаться на это.

2
ответ дан 26 November 2019 в 22:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: