根据operator new
的this reference:
全局动态存储操作符函数在标准库中比较特殊:
- operator new的所有三个版本都在全局命名空间中声明,而不是在std命名空间中声明。
- 第一个和第二个版本在C++程序的每个翻译单元中隐式声明:不需要包含标头,它们就可以存在。
在我看来,这似乎意味着operator new
的第三个版本(placement new
)并不是在C程序的每一个翻译单元中隐式声明的,并且需要包含头<new>
才能出现。对吗?
如果是这样的话,那么为什么同时使用g和MS VC++ Express编译器,我似乎可以使用new
的第三个版本编译代码而没有#include <new>
?
此外,MSDN Standard C++ Library中关于operator new
的参考条目给出了operator 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>
就无法编译的示例代码?
4条答案
按热度按时间biswetbf1#
C++中没有任何东西阻止标准头文件包含其他标准头文件。因此,如果你包括 * 任何 * 标准头,你可能会间接地包括 * 所有 * 他们。然而,这种行为完全依赖于实现,如果您需要特定头的功能,您应该始终显式地包含它。
deikduxw2#
C标准的诗句***3.7.4.2***说:-
该库为全局分配和释放函数提供默认定义。一些全局分配和释放函数是可替换的(18.6.1)。一个C程序最多只能提供一个可替换的分配或释放函数的定义。任何此类函数定义都将替换库(17.6.3.6)中提供的默认版本。下面的分配和释放函数(18.6)在程序的每个翻译单元的全局范围内隐式声明。
这些隐式声明只引入函数名
operator new
、operator new[]
、operator delete
、operator delete[]
。[注意:隐式声明不会引入名称std
、std::bad_alloc
和std::size_t
,或库用于声明这些名称的任何其他名称。因此,引用其中一个函数而不包含头文件<new>
的new-expression、delete-expression或函数调用都是格式良好的。但是,引用std
、std::bad_alloc
和std::size_t
是格式错误的,除非通过包含适当的头来声明名称。- 尾注]此外,
operator new
的std::nothrow
版本需要包含标头(example)。但是该标准没有指定头文件在其他头文件中的隐式包含。因此,当引用名称
std::bad_alloc
等时,遵循标准是安全和可移植的。wtzytmuj3#
关于标题中的问题
**"**在C++中何时需要
#include <new>
库?关键字
new
可以以各种方式使用。普通使用不需要包含任何标头。但使用此关键字的一种可能方法是调用<new>
头文件定义的特定“placement new”函数。在这种情况下,您需要直接或间接地包含<new>
头。不要包括那个头,或任何其他头,除非你需要它;默认情况下不包括标头。另一方面,不要依赖于包含另一个头的实现特定版本:总是包括你所需要的每一个标准的(或其他)规范,他们提供什么。关于体内的问题
**"**这个例子在没有这个include的情况下对我来说编译和运行似乎是一样的。
在C++中,标准库头文件允许包含其他标准库头文件(或其他标准库头文件提供的内容),这由实现决定。
ssgvzors4#
在
<new>
头中定义的运算符new
抛出bad_alloc
异常(在同一头中声明),而不是在内存分配不可能时返回NULL。<new>
头文件还定义了一个不抛出异常的变量,并放置新的变量。如果没有
<new>
,您只能得到普通的旧的、返回NULL的operator new
。所有三个运算符过载:在
<new>
头中声明。然而,一些编译器可能会隐式地使它们可用,但这是非标准的,您不应该依赖它。