参考
C++11 标准新特性:Defaulted 和 Deleted 函数
delete
c++的特殊成员函数:默认构造函数,默认拷贝构造函数,默认赋值操作符重载函数,默认析构函数。如果程序没有自己实现这些函数,但代码中需要用到的话,编译器会自己实现这些函数。有的时候不想要编译器自己实现,比如不希望有默认的拷贝构造和赋值操作符重载,就可以这样:
1 2 3 4 5 6 7 8 9 10
| class myclass { int _m; private: myclass(); ~myclass(); myclass(const myclass & param); myclass & operator=(myclass & param); };
|
将拷贝构造函数和赋值操作符重载函数作为private,并且只声明而不实现,这样就避免了编译器自动生成,而自己又不必去实现。而c++11引入了delete关键字,使用如下:
1 2 3 4 5 6 7 8 9 10
| class myclass { int _m; private: myclass() = delete; ~myclass() = delete; myclass(const myclass & param) = delete; myclass & operator=(myclass & param) = delete; };
|
这样带delete关键字的函数是不能被调用的,表示该函数被禁用。
注意:
- delete关键字可以用在类内,也可以用在类外。
- 并且delete函数也可以用在普通函数上,不一定是类的成员函数:
1 2 3 4 5 6 7
| void func(void) = delete;
int main() { func(); std::cout << "Hello World!\n"; }
|
错误(活动) E1776 无法引用 函数 "func()" (已声明 所在行数:15) -- 它是已删除的函数
delete也可以用于限制一些特定的函数类型参数对应的函数实现,具体如下:
1 2 3 4 5 6 7 8 9 10
| void func(int param) { cout << param << endl; }
int main() { func(true); func(1.2); func('a'); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void func(int param) { cout << param << endl; }
void func(bool param) = delete; void func(double param) = delete; void func(char param) = delete;
int main() { func(true); float f = 1.2; func(f); func('a'); func(1); }
|
c++98版本的策略对于类的模板函数不能生效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <iostream> using namespace std;
class myclass { public: template <typename T> void func(T param) { cout << param << endl; }
template <typename T> void func(int param); };
int main() { myclass m; char c = 'c'; m.func(c);
int i = 10; m.func(i); }
|
default
还有一种情况,默认的这几个函数,如果代码中自己实现了,则编译器不会自己再去实现了。但有些时候希望用到默认的编译器可以自己实现的函数,因为这样不用自己写起来麻烦,并且编译器自己实现的函数性能比自己实现的要高:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class myclass { int _m; public: myclass(int n):_m(n) {
} };
int main() { myclass a; return 0; }
|
错误(活动) E0291 类 “myclass” 不存在默认构造函数 ConsoleApplication6
自己实现了带参数的构造函数,编译器不会再去自己实现无参构造函数了,可以这样:
1 带缺省参数的构造函数
1 2 3 4 5 6
| public: myclass(int n = 0):_m(n) {
}
|
2 另外实现无参构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class myclass { int _m; public: myclass(int n):_m(n) {
}
myclass() {
} };
int main() { myclass a; return 0; }
|
3 什么构造函数都不实现,让编译器去实现默认的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include "pch.h" #include <iostream>
class myclass { int _m; public:
};
int main() { myclass a; return 0; }
|
4 根据需求这个类需要另外实现其他的构造函数,还想要使用编译器自己实现的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class myclass { int _m; public: myclass(int n):_m(n) {
}
myclass() = default; };
int main() { myclass a; return 0; }
|
default关键字可以让编译器去实现默认的函数
注意点:
- 只针对于这几种:默认构造函数,默认析构函数,拷贝/移动构造函数,赋值/移动赋值操作符重载函数。
- 不可用于类外
- default的函数由编译器自己实现函数体,性能比自己写的性能要高
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class myclass { int _m; public: myclass(int n):_m(n) {
}
myclass() = default; };
void func(void) = default;
int main() { myclass a; return 0; }
|
错误(活动) E1774 “= default”只能出现在默认构造函数、复制/移动构造函数、复制/移动赋值运算符和析构函数中
ending