new和delete表达式的工作步骤

new表达式的工作步骤

对于自定义类型而言,使用 new 表达式时发生的三个步骤

  1. 调用 operator new 标准库函数申请未类型化的空间

  2. 在该空间上调用该类型的构造函数初始化对象

  3. 返回指向该对象的相应类型的指针

delete表达式的工作步骤

对于自定义类型而言,使用 delete 表达式时发生的两个步骤

  1. 调用析构函数,回收数据成员申请的资源(堆空间)
  2. 调用 operator delete 库函数回收本对象所在的空间

创建对象的探究

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Demo {
public:
Demo(int n1,int n2):num1(n1),num2(n2){
std::cout<<"Demo"<<std::endl;
}
void* operator new(size_t size){ // 默认的 operator new
void* ret = malloc(size);
return ret;
}
void operator delete(void* p){ // 默认的 operator delete
free(p);
}
~Demo(){
std::cout<<"~Demo"<<std::endl;
}
private:
int num1;
int num2;
};

堆对象:需要公有的 operator new、operator delete、构造函数,对析构函数没有要求;在销毁堆对象的时候,才会调用析构函数。

堆对象.png

栈对象:需要公有的构造函数、析构函数,对 operator new / operator delete 没有要求。

栈对象.png

 

根据探究得出的结论,仍以 Student 类为例,想要实现以下需求,应该怎么做

  • 只能生成栈对象 , 不能生成堆对象

可以将 operator new/operator delete 设为私有。

  • 只能生成堆对象 ,不能生成栈对象

可以将析构函数设为私有。

总结

需要了解new / delete表达式的工作步骤,以此为依据更合理地设计类的成员函数来进行对象的创建和回收。

operator new/operator delete在平时不需要特别地写出,使用默认的即可。只在如上的特别的需求下,可以显式定义出来,实现不同的限制效果。