C++> delete关键字初探

delete有2个作用:

  1. 释放new分配的动态内存;
  2. 阻止编译器自动合成函数;

释放new分配的动态内存

delete需要与new配对使用,其参数可以是指向一块内存首地址或空指针(nullptr)。不能对同一块内存多次delete,但是可以对空指针多次delete。

注意delete和delete[] 的区别:

  • delete p 释放p指向的(单个)内存,可用于释放单个内存对象;
  • delete []p 释放p指向的内存区块,可用于释放一组内存(数组);

参见C++ delete 和 delete []的区别

示例:

// 释放基本类型内存
int *pi = new int(20);
delete pi;

// 释放类对象内存
int *ps = new string("hello");
delete ps; // 会调用string类析构函数

// 释放数组类型内存
int *pa = new int[10];
delete []pa;

阻止编译器合成函数

适用于C++11以上版本。

如果没有为类编写构造函数、析构函数、拷贝构造函数、拷贝赋值运算符,以及移动拷贝函数、移动赋值运算符,编译器可能会为类合成默认的函数版本。显式使用delete,可以阻止编译器合成对应函数。

示例:

class MyObj {
public:
  MyObj() = delete; // 阻止编译器合成构造函数,会导致类无法实例化
  MyObj& MyObj(const MyObj &) = delete; // 阻止编译器合成拷贝构造函数,会导致类无法拷贝构造,如std::cin, std::cout
  MyObj& operator=(const MyObj &) = delete; // 阻止合成赋值运算符,会导致类无法拷贝,如cin, cout, cerr
  ...
}

与delete对应的是default,default显式告诉编译器使用编译器自动合成的函数。
合成的默认构造函数,只有基类子对象和类类型对象会被初始化,而其他所有的非静态成员(如整数,指针,数组等),都不会初始化,对他们进行初始化的应该是程序员,而非编译器。

如果类包含了需要动态创建对象的指针,就不能依靠合成的构造函数、拷贝构造函数、拷贝赋值运算符。
参见C++关于编译器合成的默认构造函数

示例:

class MyObj {
public:
  MyObj() = default; // 告诉编译器合成构造函数,作为默认构造函数,类的设计者不会实现该函数
  MyObj& MyObj(const MyObj &) = default; // 告诉编译器合成拷贝构造函数,作为默认拷贝构造函数 
  MyObj& operator=(const MyObj &) = default; // 告诉编译器合成赋值运算符
  ...
}
posted @ 2021-03-18 10:33  明明1109  阅读(2421)  评论(0编辑  收藏  举报