new的理解

在编码过程中,我们常用new来分配堆内存.
MyClass *p = new Myclass;
在这个过程中,实际上经历了3个步骤:
1.调用operator new 分配堆内存;
  void *pV = operator new(sizeof(MyClass))
2.调用MyClass的构造函数
  MyClass::MyClass();
3.调用placement new 返回类对应指针
  MyClass *p = new(pV)MyClass;

new不能够被重载,只有operator new才能够被重载,operator new有6种形式:

//内存分配失败抛异常
void *operator new(std::size_t count)throw(std::bad_alloc);  
void  operator delete(void *) throw();
//内存分配失败不会抛出异常
void *operator new(std::size_t count, const std::nothrow_t&)throw();
void  operator delete(void*, const nothrow_t&) throw();  
//placement版本,不可被重载
void *operator new(std::size_t count, void *ptr) throw(){ return ptr; };

//对应的数组版本
void *operator new[](std::size_t count)throw(std::bad_alloc);
void  operator delete[](void*) throw();
void *operator new[](std::size_t count,  const std::nothrow_t&) throw();
void  operator delete[](void* p, void*) throw() { }
void* operator new[](size_t, void* ptr)  throw()  { return ptr; }
void  operator delete[](void* p, void*) throw() { }

通过对operator new的重载,可以定制自己的内存分配函数。
void* operator new(unsigned int size)
{
  cout<<"Haha,this is my operator new"<<endl;
  char * tmp_p = (char*)malloc(size);
  return tmp_p;
}

placement new 的作用是在一个已经分配好的内存中(栈和堆都可以)构造一个新的对象。
placement new 原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。
placement new实际就是直接使用之前已经分配好的内存,适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。

 

#include <iostream>
using namespace std;

enum Rank { demoted = 0, promoted = 1 };

//operator new,用num统计分配内存次数
void *operator new(std::size_t count, Rank, int , int, int)
{
  cout<<"This is my operator new"<<endl;
  static int num = 0;
  void * tmp_p = malloc(count);
  ++num;
  cout<<"allocate times: "<<num<<endl;
  return tmp_p;
}

void  operator delete(void *mem) 
{
  cout<<"This is my operator delete"<<endl;
  static int num = 0;
  free(mem);
  ++num;
  cout<<"release times: "<<num<<endl;
}

void  operator delete(void *mem, Rank, int , int, int) 
{
  cout<<"This is my operator delete with parameters"<<endl;
  static int num = 0;
  free(mem);
  ++num;
  cout<<"release times: "<<num<<endl;
}

class MyClass
{
public:
  MyClass()
  {
    cout<<"This is MyClass constructor"<<endl;
  }
  ~MyClass()
  {
    cout<<"This is MyClass destructor"<<endl;
  }  
  int var_;
};

int main()
{
  //直接使用new, delete 
  MyClass* const myClass_p =  new (demoted,1,2,3) MyClass();
  
  delete  myClass_p;
  //冒似不能直接用带参数的delete
  //delete(demoted,1,2,3)  myClass_p; 
      
  cout<<"***********************************************************************"<<endl;
  
  //调用operator new和placement new
  void * void_p = operator new(sizeof(MyClass),demoted,1,2,3);
  MyClass *myClass_p_2 = new(void_p)MyClass();
  //operator placement new
  //MyClass *myClass_p_2 = (MyClass*)(operator new(sizeof(MyClass),void_p));  
	
  myClass_p_2->~MyClass();
  operator delete (myClass_p_2);
  //带参数的delete
  //operator delete (myClass_p_2,demoted,1,2,3);  
  return 1;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值