什么时候在C ++中需要#include <new>库?

根据运营商新的参考条目( http://www.cplusplus.com/reference/std/new/operator%20new/ ):

全局dynamic存储操作符函数在标准库中是特殊的:

  • operator new的所有三个版本都在全局命名空间中声明,而不是在std命名空间中声明。
  • 第一个和第二个版本在C ++程序的每个翻译单元中都是隐含声明的:不需要包含它的头文件。

这似乎意味着,在C ++程序的每个翻译单元中,隐含地声明了operator new(placement new)的第三个版本,并且需要包含头<new>以使其存在。 那是对的吗?

如果是这样,那么如何使用g ++和MS VC ++ Express编译器,似乎我可以在我的源代码中使用没有#include <new>的第三版本编译代码?

此外,operator new上的MSDN Standard C ++库引用条目给出了包含#include <new>语句的operator new的三种forms的一些示例代码,但是,如果没有这个包含,那么该示例似乎编译和运行也是一样的?

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

谢谢。

C ++中没有任何东西阻止标准头文件包含其他标准头文件。 所以如果你包含任何标准的头文件,你可能会间接地包含所有的头文件。 然而,这个行为完全依赖于实现,如果你需要特定头文件的特性,你应该总是明确地包含它。

C ++标准第3.7.4.2节说:

该库提供了全局分配和释放函数的默认定义。 一些全球分配和释放function是可以replace的(18.6.1)。 C ++程序至多应该提供一个可replace的分配或释放函数的定义。 任何这样的函数定义都会replace库中提供的默认版本(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,或者库用于声明这些名称的任何其他名称。 因此,引用这些函数之一而不包括头部的新expression式,删除expression式或函数调用是格式良好的。 但是,引用std,std :: bad_alloc和std :: size_t是格式不正确的,除非通过包含相应的头来声明名称。 – 注意]

另外, operator newstd::nothrow版本需要包含头文件。 标准虽然没有指定在其他头文件中隐式包含头文件。 所以当名字std::bad_alloc等被引用时,遵循标准是安全和可移植的。

关于标题中的问题,

什么时候在C ++中需要#include <new>库?

关键字new可以以各种方式使用。 普通的使用不需要包含任何头文件。 但是使用这个关键字的一个可能的方法是调用由<new>头部定义的特定的“放置新的”函数。 有了这个用法,您需要直接或间接包含<new>标题。 除非您需要,否则不要包含该标题或任何其他标题; 默认情况下不包括标题。 另一方面,不要依赖包含另一个头的实现特定版本的头文件:根据标准(或其他)提供的内容,始终包含您需要的内容。

关于这个问题,

这个例子似乎编译和运行没有这个包括我一样?

在C ++标准库中,头文件允许包含其他标准库头文件(或由其他标准库头文件提供的东西),由执行者自行决定。

<new>头文件中定义的operator new会抛出bad_allocexception(在同一个头文件中声明),而不是在内存分配不可用时返回NULL。 头文件也定义了

 void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw(); 

不会抛出exception和放置新变种的变体。 没有<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>标题中声明。 但是,一些编译器可能会隐式地使用它们,但是这是非标准的,你不应该依赖它。