根据this reference for
operator new
:
全球动态存储运营商 功能在标准中是特殊的 图书馆:
- operator new 的三个版本都在全局命名空间中声明, 不在 std 命名空间中。
- 第一个和第二个版本隐式声明在每个 C++程序的翻译单元: 标头不需要 包括在内,以便他们在场。
在我看来,这意味着
operator new
的第三个版本(放置new
)并没有在C++程序的每个翻译单元中隐式声明,并且需要包含头文件<new>
才能出现。对吗?
如果是这样,为什么同时使用 g++ 和 MS VC++ Express 编译器似乎我可以使用第三版
new
编译代码而源代码中没有#include <new>
?
此外,MSDN 标准 C++ 库参考条目
operator new
给出了三种形式的operator 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>
将无法编译?
C++ 中没有任何东西可以阻止标准头文件包含其他标准头文件。因此,如果您包含 any 标准标头,您可能会间接包含 all 它们。然而,这种行为完全依赖于实现,如果您需要特定标头的功能,您应该始终自己明确包含它。
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
,或图书馆用来声明的任何其他名称 这些名字。因此,new 表达式、delete 表达式或函数 引用这些函数之一的调用,不包括 headerstd::size_t
格式正确。但是,参考<new>
,std
,并且std::bad_alloc
是病态的,除非名字已经被 通过包含适当的标题来声明。 ——尾注]std::size_t
另外,
std::nothrow
的operator new
版本需要包含标题(example)。
虽然标准没有指定在其他头文件中隐式包含头文件。所以在引用名字
std::bad_alloc
等时遵循标准是安全和便携的。
关于标题中的问题,
” C++ 什么时候需要
库?#include <new>
关键字
new
可以以多种方式使用。普通使用不需要包含任何标题。但是使用此关键字的一种可能方法是调用 <new>
标头定义的特定“placement new”函数。使用该用法,您需要直接或间接包含 <new>
标头。除非您需要,否则不要包含该标头或任何其他标头;默认情况下不包含标题。另一方面,不要依赖包含另一个标头的实现特定版本:始终根据标准(或其他)提供的规范包含您需要的内容。
关于正文中的问题,
” 在没有这个包含的情况下,这个例子似乎对我来说编译和运行是一样的?
在 C++ 中,标准库头文件允许包含其他标准库头文件(或其他标准库头文件提供的内容),由实现自行决定。
new
标头中定义的Operator
<new>
抛出 bad_alloc
异常(在同一标头中声明)而不是在无法分配内存时返回 NULL。 <new>
header 也定义了
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>
标头中声明。然而,一些编译器可能使它们隐式可用,但这是非标准的,你不应该依赖它。