New运算符详解

三种new运算符:

new运算符做的三件事:获得一块内存空间、调用构造函数、返回正确的指针

1、new

分配内存,调用构造函数,定义如下:

void* operator new(std::size_t) throw(std::bad_alloc);

void operator delete(void *) throw();

分配失败则抛出异常std::bad_alloc,不是返回NULL,所以判断返回值是否为NULL是没用的。

char *p=new char[size]; //分配失败,不是返回NULL

delete [] p;

2、nothrow new

不抛出异常。分配失败时,返回NULL。定义如下:

void* operator new(std::size_t,const std::nothrow_t&) throw();

void operator delete(void*) throw();

char *p=new(nothrow) char[size];//分配失败,是返回NULL

    if(NULL==p)

    cout<<"alloc failure!"<<endl;

3、placement new

不会内存分配失败,因为它根本不分配内存,只调用对象的构造函数。它允许在一块已经分配成功的内存上重新构造对象或对象数组。定义如下:

void* operator new(size_t,void*);

void operator delete(void*,void*);

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

当使用new运算符定义一个多维数组变量或数组对象时,它产生一个指向数组第一个元素的指针,返回的类型保持了除最左边维数外的所有维数。

New运算符的使用方法:

1、new() :分配这种类型的一个大小的内存空间,并以括号中的值来初始化这个变量;

2、 new[] :分配这种类型的n个大小的内存空间,并用默认构造函数来初始化这些变量;  

char* p=new char[6];     strcpy(p,"Hello");

3、当使用new运算符定义一个多维数组变量或数组对象时,它产生一个指向数组第一个元素的指针,返回的类型保持了除最左边维数外的所有维数。例如:  

int *p1 = new int[10];

返回的是一个指向int的指针int*  

int (*p2)[10] = new int[2][10];

new了一个二维数组, 去掉最左边那一维[2], 剩下int[10], 所以返回的是一个指向int[10]这种一维数组的指针int (*)[10].  

int (*p3)[2][10] = new int[5][2][10];

 new了一个三维数组, 去掉最左边那一维[5], 还有int[2][10], 所以返回的是一个指向二维数组int[2][10]这种类型的指针int (*)[2][10].

4、创建类对象

1)new创建对象,pTest用来接收对象指针。new申请的对象,则只有调用到delete时才会执行析构函数,如果程序退出而没有执行delete则会造成内存泄漏:

CTest*  pTest = new  CTest();  delete pTest;

2)不用new,直接使用类定义申明,使用完后不需要手动释放,该类析构函数会自动执行:

CTest  mTest;

3)使用普通方式创建的类对象,在创建之初就已经分配了内存空间。而类指针,如果未经过对象初始化,则不需要delete释放:

CTest*  pTest = NULL;

 

 

 

 

猜你喜欢

转载自blog.csdn.net/growth_path_/article/details/83927810