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

问题描述 投票:0回答:4

根据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++ new-operator include standard-library
4个回答
18
投票

C++ 中没有任何东西可以阻止标准头文件包含其他标准头文件。因此,如果您包含 any 标准标头,您可能会间接包含 all 它们。然而,这种行为完全依赖于实现,如果您需要特定标头的功能,您应该始终自己明确包含它。


16
投票

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
,或图书馆用来声明的任何其他名称 这些名字。因此,new 表达式、delete 表达式或函数 引用这些函数之一的调用,不包括 header
<new>
格式正确。但是,参考
std
std::bad_alloc
,并且
std::size_t
是病态的,除非名字已经被 通过包含适当的标题来声明。 ——尾注]

另外,

std::nothrow
operator new
版本需要包含标题(example)。

虽然标准没有指定在其他头文件中隐式包含头文件。所以在引用名字

std::bad_alloc
等时遵循标准是安全和便携的。


6
投票

关于标题中的问题,

C++ 什么时候需要

#include <new>
库?

关键字

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

关于正文中的问题,

在没有这个包含的情况下,这个例子似乎对我来说编译和运行是一样的?

在 C++ 中,标准库头文件允许包含其他标准库头文件(或其他标准库头文件提供的内容),由实现自行决定。


4
投票

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>
标头中声明。然而,一些编译器可能使它们隐式可用,但这是非标准的,你不应该依赖它。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.