C++11 delete
简介
delete
声明的函数也会参与匹配,但是编译阶段就明确此类型的函数已被删除.
delete
的错误可以在编译阶段发现.回顾
C++98
声明为
private
且不定义. 链接 阶段才能发现.
delete
解决的问题
C++
编译器
默认为类创建: 无参构造,析构,拷贝,赋值四个函数.
冲突的就是: 拷贝赋值这两个函数.
c++98
- 通过
private
私有声明并不定义以此达到目的.但是只能链接阶段才能检测到错误.代码是先编译,再链接,而链接是最后一步,最后一步才发现可能会过很久,特别是大型的项目编译.
c++11
C++98
的手段在C++11
中被加强错误识别时间,编译阶段就可以识别出来.所以建议采用
C++11
而不是C++98
.隐式转换
- 类型之间的隐式转换也会导致不匹配的类型转换调用。
- 可以通过声明一个对应类型的声明,然后标记为
delete
就可以规避.不过之类比较麻烦.
隐式案例
void cool(int) {} void cool(bool) = delete; int main() { cool(1); cool(false); }
后面的会失败.
两种版本的编译
[root@localhost test]# g++ -c test.cpp -std=c++98 [root@localhost test]# gcc test.o test.o: In function `main': test.cpp:(.text+0x1d): undefined reference to `cool(bool)' collect2: error: ld returned 1 exit status [root@localhost test]# cat test.cpp void cool(int) {} void cool(bool); int main() { cool(1); cool(false); } [root@localhost test]# vim test.cpp [root@localhost test]# g++ -c test.cpp -std=c++11 test.cpp: In function ‘int main()’: test.cpp:6:15: error: use of deleted function ‘void cool(bool)’ cool(false); ^ test.cpp:2:6: error: declared here void cool(bool) = delete; ^ [root@localhost test]# cat test.cpp void cool(int) {} void cool(bool) = delete; int main() { cool(1); cool(false); }
编译阶段发现错误.
差异
C++11
public
中声明函数,并标记为delete
.
private
则会先检测权限再检测是否delete
,得到错误信息.
C++98
私有不定义,在链接阶段才能发现问题. 太迟了.
私有拷贝或者赋值对于友元或者成员中可能用到. 仍然只能在链接阶段才发现.
delete
的强大
强大之处
什么函数都可以
delete
. 普通函数,模板,类等等,几乎所有.全局函数
delete
void cool(int) {} void cool(bool) = delete; int main() { cool(1); cool(false); }
这里的案例不严谨,可能还有
const,volatile
之类的修饰会影响,但这里仅仅是个案例.禁止模板实例化
template <typename T> void show(T a) {} template<> void show<bool>(bool) = delete; int main() { show(1); show(false); }
show(bool)
不能被实例化.这里的案例也不是很完善,虽然也可能是
const,volatile
之类的.类成员
class T { public: template <typename T> void show(T a) {} template<> void show<bool>(bool) = delete; }; int main() { T a; a.show(1); a.show(false); }
编译报错,编译器不允许在类中特例化.
只能在全局或者命名空间里面.
C++11
标准版class T { public: template <typename T> void show(T a) {} }; template<> void T::show<bool>(bool) = delete; int main() { T a; a.show(1); a.show(false); }
还是报错,不允许
bool
类型的特例化.
总结
C++98
的private
声明不定义是可以,但是链接阶段才能发现.
C++11
的public
中delete
则在编译阶段即可.
delete
支持禁止普通函数,模板函数,的实例化.更加强大.