new和delete重载(1)

本文深入探讨C++中new和delete操作符的使用方法及其重载机制。解释了global new/delete与placement new/delete的区别,并通过具体代码示例展示了它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

new和delete是语言关键字,它分为两个部分

new:operator new(申请空间)------构造函数初始化

delete:析构函数析构---------------operator delete(释放空间)

而在operator new 和operator delete中又分为global new和placement new以及global delete和placement delete

一般所谓的重载new和delete只是重载operator new和operator delete

 

以下分析global new和global delete

void *operator new(unsigned int a)//(1)

{

  printf("new/n");

  return malloc(a);

};

void *operator new(unsigned int a, bool)//(2)

{

  printf("bool new/n");

  return operator new(a);

};

 

void *operator new[](unsigned int a)//(3)

{

  printf("new array/n");

  return malloc(a);

};

 

void operator delete(void *memP)//(4)

{

  printf("delete/n");

  free(memP);

};

void operator delete(void *memP, bool)//(5)

{

  printf("bool delete/n");

  operator delete(memP);

};

 

void operator delete[](void *memP)//(6)

{

  printf("delete array/n");

  free(memP);

};

 

void main() 

  int* pa1 = new(0) int(0);//call 2

  delete pa1;//call 4

  int* pa2 = new int;//call 1

  delete pa2;//call 4

  int* pa3 = new int;//call 1

  operator delete(pa3, 0);//call 5

  int* pa4 = new(0) int;//call 2

  delete(0) pa4;//编译错误,测试平台为VC6.0(我觉得不应该会有问题,应该是编译器的问题,暂时还没有在其它编译器下尝试过)

 

  int* paArray = new int[10];//call 3

  delete[] paArray;//call 6

 

  int* pa1 = new(0) int(0);//call 2 这个就是典型的先申请空间然后够早初始化

 

以下placement new和placement delete

#include <stdlib.h>

#include<stdio.h>

class AAA

{

  public:

    AAA(){printf("AAA constructor!!!/n");}

    static void * operator new(unsigned int size){printf("AAA:new/n");return malloc(size);}//(1)

    static void operator delete(void *memP){printf("AAA:delete/n");free(memP);}//(2)

    static void * operator new(unsigned int size, bool){printf("AAA:bool new/n"); return malloc(size);}//(3)

    static void operator delete(void *memP, bool){printf("AAA:bool delete/n");free(memP);}//(4)

    static void * operator new[](unsigned int size){printf("AAA:new array/n");return malloc(size);}//(5)

    static void operator delete[](void *memP){printf("AAA:delete array/n");free(memP);}//(6)

    ~AAA(){printf("AAA destructor!!!/n");}

};

 

class BBB:public AAA

{

  public:

    BBB(){printf("BBB constructor!!!/n");}

    ~BBB(){printf("BBB destructor!!!/n");}

};

 

class CCC

{

  public:

    CCC(){printf("CCC constructor!!!/n");}

    static void * operator new(unsigned int size){printf("CCC:new/n");return malloc(size);}//(7)

    static void operator delete(void *memP){printf("CCC:delete/n");free(memP);}//(8)

    static void * operator new(unsigned int size, bool){printf("CCC:bool new/n");return malloc(size);}//(9)

    static void operator delete(void *memP, bool){printf("CCC:bool delete/n");free(memP);}//(10)

    ~CCC(){printf("CCC destructor!!!/n");}

};

 

void main()

{

  AAA* aaa1P = new AAA;//call 1

  delete aaa1P;//call 2

  AAA* aaa2P = new(true) AAA;//call 3

  delete(true) aaa2P;//编译不过

  AAA::operator delete(aaa2P, true);//call 4

  AAA* aaa3P = new AAA[10];//call 5

  delete[] aaa3P;//call 6

  AAA* aaa4P = new AAA[10];//call 5

  AAA::operator delete[](aaa4P);//call 6 vc6.0下会出现执行错误

  BBB* bbb1P = new BBB;//call 1

  delete bbb1P;//call 2

  BBB* bbb2P = new(true) BBB;//call 3

  BBB::operator delete(bbb2P, true);//call 4

  CCC* ccc1P = new CCC;//call 7

  delete ccc1P;//call 8

  CCC* ccc2P = new(true) CCC;//call 9

  CCC::operator delete(ccc2P, true);//call 10  

}

注:

1.  AAA* aaa3P = new AAA[10];//call 5

  先会生成10个AAA类对象的空间,然后在每个AAA空间中执行构造函数,而不是每new一个AAA对象空间,再执行AAA的构造函数

  delete[] aaa3P;//call 6

先执行10个AAA对象的析构函数,然后释放10个AAA对象的空间

  AAA* aaa4P = new AAA[10];//call 5  

  AAA::operator delete(aaa4P);//call 6

这样调用仅仅是释放空间,而不会调用析构函数,这样比较危险,一般不建议这样做

BBB类中虽然没有重载new和delete,但是它继承了AAA的new和delete,这样做会比较危险(可能造成内存泄漏,下回分析)

 

2.为什么placement new和delete是static?

以new为例,operator new申请空间之前,构造函数还未执行,也就没有this指针,所以它必须是static,属于这个类而不是属于某个对象

 

globa和placement混合用

#include <stdlib.h>

#include<stdio.h>

class AAA

{

public:

  AAA(){printf("AAA constructor!!!/n");}

  static void * operator new(unsigned int size){printf("AAA:new/n");return malloc(size);}

  static void operator delete(void *memP){printf("AAA:delete/n");free(memP);}

  static void * operator new[](unsigned int size){printf("AAA:new array/n");return malloc(size);}

  static void operator delete[](void *memP){printf("AAA:delete array/n");free(memP);}

  static void * operator new(unsigned int size, bool){printf("AAA:bool new/n"); return malloc(size);}

  static void operator delete(void *memP, bool){printf("AAA:bool delete/n");free(memP);}

  ~AAA(){printf("AAA destructor!!!/n");}

};

 

void *operator new(unsigned int a)

{

  printf("new/n");

  return malloc(a);

};

 

void *operator new[](unsigned int a)

{

  printf("new array/n");

  return malloc(a);

};

 

void *operator new(unsigned int a, bool)

{

  printf("bool new/n");

  return operator new(a);

};

void operator delete(void *memP)

{

  printf("delete/n");

  free(memP);

};

void operator delete[](void *memP)

{

  printf("delete array/n");

  free(memP);

};

void operator delete(void *memP, bool)

{

  printf("bool delete/n");

  operator delete(memP);

};

void main() 

  int* pa = new(0) int(0);

  delete pa;

  int* paArray = new int[10];

  delete[] paArray;

  AAA* pAAA = new AAA;

  delete pAAA;

  AAA* pAAAArray = new AAA[10];//执行AAA::operator new[]

如果AAA中没有重载new,则执行的是global new

  AAA::operator delete[](pAAAArray);//执行AAA::operator delete[]执行错误

//   delete[] pAAAArray;///执行AAA::operator delete[]和相应的析构函数

如果AAA中没有重载delete,则执行的是global delete

 

终上所述:

1.重载new第一个参数必须是unsigned int,返回值必须是void*;

   重载delete第一个参数必须是void*,返回值必须为void

2.在vc6.0下,除了显式调用除operator delete(void*)形式以外的operator delete函数,不能殷实调用delete

3.从第三个例子可以看出来,其实global和placement都是一样的,placement形式是static类型,其实也是一个全局的函数,只是它受保护,不能随便被外部调用到。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值