《More Effective C++》8:了解各种不同意义的new和delete

来源:互联网 发布:简易编程软件swift 编辑:程序博客网 时间:2024/05/17 22:15

new operator 和 operator new

当你写出这样的代码时,实际上你调用的是所谓的new operator:

string* pS = new string("Hello, New Operator.");

呵呵,别纠结,我们来理一理它们的“情感纠纷”。

其实,当我们在做上面的所谓new operator操作时,做了两件事情,

其一,开辟用来存string对象的空间;

其二,调用该对象的构造函数,将该对象初始化。

第一步的操作,实际上是编译器在调用一个专管分配内存的操作符,这就是所谓的operator new操作符,

它和malloc函数一样,唯一的任务就是内存分配,因此,上面的那段代码的具体实现是这样的:

void* memory = operator new(sizeof(string));//开辟string对象的空间调用string::string("Hello, New Operator.")将memory初始化string * pS = static_cast<string*>(memory); //让pS指向新创建的对象

placement new

在已经分配好空间的原始的,未初始化的内存中,如何构造对象呢?

显然直接调用构造函数就有点奇葩了,毕竟构造函数是在创建新对象时候初始化对象的,

而现在针对的是在已建空间上构建对象。

有一个特殊的operator new,名为placement new可以实现该内容。

看下面的例子:

void* memory = operator new(sizeof(string));//开辟string对象的空间cout << "memory指向的空间:" << memory << endl;string* p = new (memory) string("hello, new operator.");cout << "p指向的空间:     " << p << endl;cout <<"p指向的内容:" << *p << endl;
效果:

string* p = new (memory) string("hello, new operator."); 从结果来看,这句话就是在把分配到memory的内容初始化为string。

这就是所谓的placement new.

删除(Deletion)和内存释放(Deallocation)

为了避免资源泄露(Resource Leaks)。每一个动态分配行为,都必须有一个与之对应但相反的释放动作。

因此,函数operator delete 之于内建的 delete operator,相当于 operator new 之于 new operator。

当做下面的操作时,

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. delete pS;  
编译器会产生近似这样的代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. pS->~string();  
  2. operator delete(pS);  

数组

当然,在之前我们一直谈到的是分配单一对象的空间,要是我们要用 new operator产生一个数组空间,就会有所不同。

在分配内存阶段,‘不能再调用 operator new来操作,而是调用一个名为 operator  new[ ]的函数负责分配内存。

同样道理,当delete operator 被用于数组,它就会针对每一个对象调用其析构函数,

然后调用其operator delete[ ]函数释放内存。


1 0
原创粉丝点击