new operator  new操作符

operator new  操作符new

placement new  定位new

string *ps = new string("Memory Management"); 

这里的new是new 操作符。这里共有两个步骤的工作要做:

①为对象申请空间 ②调用构造函数初始化内存中的对象

new 操作符总是做这两件事,不可以任何方式改变其行为。

但是你可以改变步骤①如何为对象申请空间。

new 操作符是通过 operator new这个函数为对象申请空间。

operator new 的声明形式

void* operator new(size_t size);//在做其他形式重载时也要保证第一个参数必须为size_t类型

函数的返回值是 void*,参数size确定分配多少内存

该函数调用时与普通函数一样

ST *pt = operator new(sizeof(ST));

placement new的作用是在已经被分配但是尚未处理的(raw)内存中构造一个对象。它是一个特殊的operator new

void* operator new(size_t, void *p)//参数size_t没有名字,但是为了防止编译器警告必须加上
{
return p;
}

在使用placement new时调用者已经获得了指向内存的指针,因为调用者知道对象应该放在

哪里。placement new必须做的就是返回传递给它的指针。

总结:如果你想在堆上建立一个对象,应该使用new 操作符,它既分配内存又为对象调用构造函数;

   如果你只想分配内存,就调用operator new函数,它不会调用构造函数;

    如果你想定制自己的在堆对象被建立时的内存分配过程,你应该写自己的operator new 函数,然后使用

new操作符,new操作符会调用你定制的operator new。

   如果你想在一块已经获得指针的内存里建立一个对象,应该使用palcement new.

#include<iostream>
#include<vld.h>
using namespace std;
class ST
{
private:
char *ptr;
public:
ST(const char *str = ""):ptr("")
{
cout<<"Object was built. "<<endl;
if(str == NULL)
{
this->ptr = new char[1];
this->ptr[0] = '\0';
}
else
{
this->ptr = new char [strlen(str)+1];
strcpy(ptr, str);
}
}
~ST()
{
cout<<"Object was free. "<<endl;
delete []this->ptr;
ptr = NULL;
}
void* operator new(size_t, void *p)//placement new
{
return p;
}
void operator delete(void *p)
{
cout<<"---"<<endl;
free(p);
}
};
void* operator new(size_t t)
{
void *p = malloc(t);
return p;
}void* operator new[](size_t t)
{
void *p = malloc(t);
return p;
}
void operator delete[](void *p)
{
cout<<"--[][]\n";
free(p);
return;
}
void main()
{
ST *pt = (ST*)operator new (sizeof(ST)); //使用重载的operator new 为对象pt分配空间
new(pt)ST("Hello");      //这里调用placement new,同时也调用了构造函数。前两行代码等价于在未重载new时 ST *pt = new ST("Hello");
pt->~ST();           //通过pt指针可直接调用析构函数,但是不可调用构造函数
operator delete (pt);    //调用operator delete函数 后行代码等价于在未重载delete时 delete pt

运行结果

为了避免内存泄漏,每个动态内存分配必须与一个等同相反的deallocation对应。

函数operator delete与delete操作符的关系和operator new与new操作符一样。

注意,在使用placement new在内存建立对象时,应避免使用delete操作符。

应该显式调用对象的析构函数来解除构造函数的影响。

在为对象数组申请空间时必可重载 operator new[] 函数而不再使用operator new函数。

例如

ST *pt = new ST[3];

这个过程共调用3次构造函数

将上例主函数修改为

void main()
{
ST *pr = new ST[3];
delete[] pr;//[]一定不可缺少
}

运行结果为

最新文章

  1. 查看Windows下引起Oracle CPU占用率高的神器-qslice
  2. C算法编程题系列
  3. Jquery开灯关灯效果
  4. springMVC工作机制和框架搭建配置说明
  5. 2dx中文乱码问题
  6. Java.util.concurrent包学习(一) BlockingQueue接口
  7. Linux系统性能监控
  8. 用python理解web并发模型
  9. [C#]生成预定义全颜色表
  10. 开心系列学习笔记---------javascript(7)
  11. CSS中字体尺寸总结
  12. TeamViewer——可以实现在手机上随时远程控制你的电脑
  13. 分页查询不知你是否真正的懂和PHP的正则的应用和一些性能优化
  14. The Ultimate Guide To iPhone Resolutions
  15. 前端笔记之Canvas
  16. lombok的安装
  17. 重建程序员能力(3)-asp.net MVC框架增加Controller
  18. jsp页面怎么引入js
  19. [Leetcode 216]求给定和的数集合 Combination Sum III
  20. SPI有关CPOL和CPHA的时序图

热门文章

  1. sql注入理解
  2. php linux yaml 的安装和使用
  3. 『学了就忘』Linux基础命令 — 30、find命令详细说明
  4. Vue首屏性能优化组件
  5. JDK源码阅读(5):HashTable类阅读笔记
  6. 【.NET 与树莓派】用 MPD 制作数字音乐播放器
  7. 浅谈springboot自动配置原理
  8. PTA 7-1 是否完全二叉搜索树 (30分)
  9. rocketmq有序消息的(四)
  10. 在Jenkins中执行 PowerShell 命令实现高效的CD/CI部署