C++中有几种类型的new(plain new\nothrow new\placement new)

心已赠人 2022-09-09 04:48 319阅读 0赞

C++中有几种类型的new

在C++中,new有三种典型的使用方法:plain new,nothrow new和placement new

  • plain new

言下之意就是普通的new,就是我们常用的new,在C++中定义如下:

void* operator new(std::size_t) throw(std::bad_alloc);
void operator delete(void *) throw();
Copy to clipboardErrorCopied
因此plain new在空间分配失败的情况下,抛出异常std::bad_alloc而不是返回NULL,因此通过判断返回值是否为NULL是徒劳的,举个例子:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main()
  5. {
  6. try
  7. {
  8. char *p = new char[10e11];
  9. delete p;
  10. }
  11. catch (const std::bad_alloc &ex)
  12. {
  13. cout << ex.what() << endl;
  14. }
  15. return 0;
  16. }

//执行结果:bad allocation
Copy to clipboardErrorCopied

  • nothrow new

nothrow new在空间分配失败的情况下是不抛出异常,而是返回NULL,定义如下:

void * operator new(std::size_t,const std::nothrow_t&) throw();
void operator delete(void*) throw();
Copy to clipboardErrorCopied
举个例子:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main()
  5. {
  6. char *p = new(nothrow) char[10e11];
  7. if (p == NULL)
  8. {
  9. cout << "alloc failed" << endl;
  10. }
  11. delete p;
  12. return 0;
  13. }

//运行结果:alloc failed
Copy to clipboardErrorCopied

  • placement new

这种new允许在一块已经分配成功的内存上重新构造对象或对象数组。placement new不用担心内存分配失败,因为它根本不分配内存,它做的唯一一件事情就是调用对象的构造函数。定义如下:

void* operator new(size_t,void*);
void operator delete(void*,void*);
Copy to clipboardErrorCopied
使用placement new需要注意两点:

palcement new的主要用途就是反复使用一块较大的动态分配的内存来构造不同类型的对象或者他们的数组

placement new构造起来的对象数组,要显式的调用他们的析构函数来销毁(析构函数并不释放对象的内存),千万不要使用delete,这是因为placement new构造起来的对象或数组大小并不一定等于原来分配的内存大小,使用delete会造成内存泄漏或者之后释放内存时出现运行时错误。

举个例子:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class ADT{
  5. int i;
  6. int j;
  7. public:
  8. ADT(){
  9. i = 10;
  10. j = 100;
  11. cout << "ADT construct i=" << i << "j="<<j <<endl;
  12. }
  13. ~ADT(){
  14. cout << "ADT destruct" << endl;
  15. }
  16. };
  17. int main()
  18. {
  19. char *p = new(nothrow) char[sizeof ADT + 1];
  20. if (p == NULL) {
  21. cout << "alloc failed" << endl;
  22. }
  23. ADT *q = new(p) ADT; //placement new:不必担心失败,只要p所指对象的的空间足够ADT创建即可
  24. //delete q;//错误!不能在此处调用delete q;
  25. q->ADT::~ADT();//显示调用析构函数
  26. delete[] p;
  27. return 0;
  28. }

//输出结果:
//ADT construct i=10j=100
//ADT destruct

发表评论

表情:
评论列表 (有 0 条评论,319人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java变量类型

    在Java语言中,变量的类型主要分为3种:成员变量,静态变量和局部变量。 1. 类的成员变量的作用范围与类的实例化对象的作用范围相同,当类被实例化,成员变量就会在内存中分配

    相关 .net New用法

    3种。 1)new 运算符:用于创建对象和调用构造函数。 2)new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。 3)new 约束:用于在