禁止拷贝构造,禁止bug
一、前言
首先,我先讲讲为什么会写这篇文章;这个也是翻阅自己之前博客,当时看开源代码的时候,总是很奇怪,为什么有的代码中会会出现类似于这样的代码产生,当时大概查阅了一下资料,只是说这个代码的意思是将默认的拷贝构造函数禁止了,但是并没有了解到为什么这样做,直到前几天思考了这个问题,觉得有必要写下来,并且分享一下,也为自己做一个笔记,在今后的开发过程中,多留一个心眼,少踩一个坑~
二、拷贝构造函数
我们先来认识下什么是拷贝构造函数;
拷贝构造函数是一个特殊的构造函数,一般只有一个参数,这个参数一般是用const修饰的,对自己类的一个引用。
在编写程序的时候,如果我们没有编写拷贝构造函数,那么编译器会为我们自动生成一个拷贝构造函数。
下面看一下最简单的构造函数使用吧(使用默认构造函数)
我们自己编写一个简单的拷贝构造函数:
结果:
什么情况下会调用拷贝构造函数?
主要有以下几方面:
对象以值作为函数参数传递
代码演示:
结果:
具体对象构造过程:
g_Fun 函数会产生临时变量C()
调用拷贝构造函数赋值C
g_Fun函数执行完毕后,会析构掉临时变量
一个对象初始化另外一个对象
例子:(开始的案例)
还有一种说法是当对象作为值的形式作为函数的额返回值
比如:
这中形式的调用拷贝构造函数,根据编译器不同就会被优化,经过测试windows 环境下vs调式是会调用拷贝构造函数的,但是在linux下g++编译后,就进行了优化,直接通过堆栈返回对象,少调用一次拷贝构造函数。
三、禁用拷贝构造函数
上面我们回顾了拷贝构造函数的概念以及会调用拷贝构造函数的场景,感觉并没有异常发生,一切都函数那么友好,那么顺利,无论使用我们编写的构造函数还是使用默认拷贝构造函数,那么我们看一个例子,也许大家会有一些思考:
看下这个案例:
先不要看答案,大家可以思考下~
我们可以编译运行下,会出现什么现象:
发现运行的直接崩溃了~
就我们获取下core文件,然后看下堆栈信息:
从堆栈信息大致可以得出,我们程序出现异常的是在23行,并且在析构的时候发生了异常;
所以得出结论:
不是所有的默认拷贝构造函数都是安全的,在我们不需要拷贝构造函数的时候,我们可以把默认拷贝构造函数禁止使用,这样就不会出现因为默认拷贝构造函数导致难以寻找的BUG!!!
四、如何禁止拷贝构造函数
禁止拷贝构造构造函数有两种方式,一般我们使用第一种,是最简单的,也是C++11的新特性~
使用delete关键字
我们可以直接使用关键字进行禁止默认拷贝构造函数
使用 基类
我们可以使用:
使用以上两种方式,我们可以禁止默认拷贝函数,如果需要拷贝构造函数,我们可以自己进行编写程序;
禁止默认拷贝构造,禁止BUG!
领取专属 10元无门槛券
私享最新 技术干货