5.2 =delete 显式删除函数
=delete 显式删除函数用于指示编译器禁用自动生成该成员函数,任何试图调用该函数的代码都会在编译时报错。
=delete 显式删除函数可以用于任何成员函数(包括特殊成员函数和普通成员函数)。
显式删除函数的适用场景如下:
- 禁止拷贝(单例模式、资源独占类)。
- 禁止某些隐式类型转换。
- 禁用不需要的特定重载版本。
示例1
禁止 Complex 类型的的对象拷贝。
// filename: delete1.cpp
class Complex {
public:
Complex(double r=0.0, double i=0.0): real(r), image(i){}
Complex(const Complex & other) = delete;
Complex& operator=(const Complex & other) = delete;
private:
double real;
double image;
};
int main(int argc, char * argv[]) {
Complex c1(1, 2);
Complex c2(c1); // 报错,禁止拷贝构造
Complex c3;
c3 = c1; // 报错,禁止拷贝
return 0;
}
编译时报错如下:
weimz@mzstudio:~$ gcc -o delete1 delete1.cpp
delete1.cpp: In function ‘int main(int, char**)’:
delete1.cpp:13:18: error: use of deleted function ‘Complex::Complex(const Complex&)’
13 | Complex c2(c1); // 报错,禁止拷贝构造
| ^
delete1.cpp:4:9: note: declared here
4 | Complex(const Complex & other) = delete;
| ^~~~~~~
delete1.cpp:13:18: note: use ‘-fdiagnostics-all-candidates’ to display considered candidates
13 | Complex c2(c1); // 报错,禁止拷贝构造
| ^
delete1.cpp:15:10: error: use of deleted function ‘Complex Complex::operator=(const Complex&)’
15 | c3 = c1; // 报错,禁止拷贝赋值
| ^~
delete1.cpp:5:17: note: declared here
5 | Complex operator=(const Complex & other) = delete;
| ^~~~~~
示例2
禁止 double 类型转为 int 类型的隐式类型转换。
// filename: delete2.cpp
class Human {
public:
Human(): age(0){}
void set_age(int a) { age = a; }
void set_age(double) = delete; // 禁止设置浮点数年龄。
private:
int age;
};
int main(int argc, char * argv[]) {
Human h1;
h1.set_age(18); // 正确用法。
h1.set_age(16.5); // 错误,已经禁止 set_age(double)。
return 0;
}
编译时报错如下:
weimz@mzstudio:~$ g++ -o default2 default2.cpp
default2.cpp: In function ‘int main(int, char**)’:
default2.cpp:14:15: error: use of deleted function ‘void Human::set_age(double)’
14 | h1.set_age(16.5); // 错误,已经禁止 set_age(double)。
| ~~~~~~~~~~^~~~~~
default2.cpp:6:14: note: declared here
6 | void set_age(double) = delete; // 禁止设置浮点数年龄。
| ^~~~~~~
default2.cpp:14:15: note: use ‘-fdiagnostics-all-candidates’ to display considered candidates
14 | h1.set_age(16.5); // 错误,已经禁止 set_age(double)。
| ~~~~~~~~~~^~~~~~
make: *** [Makefile:35:default1] 错误 1
示例3
禁止 Image 类型的对象只能移动构造或移动赋值,不能复制。
// filename: delete3.cpp
class Image {
public:
Image() = default
// 只允许移动,不允许拷贝
Image(Image&&) = default;
Image& operator=(Image&&) = default;
// 禁止复制
Image(const Image&) = delete;
Image& operator=(const Image&) = delete;
};