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

umuewwlo  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(114)

根据operator newthis 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>就无法编译的示例代码?

biswetbf

biswetbf1#

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

deikduxw

deikduxw2#

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 newoperator new[]operator deleteoperator delete[]。[注意:隐式声明不会引入名称stdstd::bad_allocstd::size_t,或库用于声明这些名称的任何其他名称。因此,引用其中一个函数而不包含头文件<new>的new-expression、delete-expression或函数调用都是格式良好的。但是,引用stdstd::bad_allocstd::size_t是格式错误的,除非通过包含适当的头来声明名称。- 尾注]
此外,operator newstd::nothrow版本需要包含标头(example)。
但是该标准没有指定头文件在其他头文件中的隐式包含。因此,当引用名称std::bad_alloc等时,遵循标准是安全和可移植的。

wtzytmuj

wtzytmuj3#

关于标题中的问题

**"**在C++中何时需要#include <new>库?

关键字new可以以各种方式使用。普通使用不需要包含任何标头。但使用此关键字的一种可能方法是调用<new>头文件定义的特定“placement new”函数。在这种情况下,您需要直接或间接地包含<new>头。不要包括那个头,或任何其他头,除非你需要它;默认情况下不包括标头。另一方面,不要依赖于包含另一个头的实现特定版本:总是包括你所需要的每一个标准的(或其他)规范,他们提供什么。
关于体内的问题

**"**这个例子在没有这个include的情况下对我来说编译和运行似乎是一样的。

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

ssgvzors

ssgvzors4#

<new>头中定义的运算符new抛出bad_alloc异常(在同一头中声明),而不是在内存分配不可能时返回NULL。<new>头文件还定义了

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

相关问题