禁止拷贝构造,禁止bug
禁止拷贝构造 , 禁止bug
文章插图
文章插图
一、前言 首先 , 我先讲讲为什么会写这篇文章;这个也是翻阅自己之前博客 , 当时看开源代码的时候 , 总是很奇怪 , 为什么有的代码中会会出现类似于Epoll( const Epoll这样的代码产生 , 当时大概查阅了一下资料 , 只是说这个代码的意思是将默认的拷贝构造函数禁止了 , 但是并没有了解到为什么这样做 , 直到前几天思考了这个问题 , 觉得有必要写下来 , 并且分享一下 , 也为自己做一个笔记 , 在今后的开发过程中 , 多留一个心眼 , 少踩一个坑~
二、拷贝构造函数我们先来认识下什么是拷贝构造函数;
拷贝构造函数是一个特殊的构造函数 , 一般只有一个参数 , 这个参数一般是用const修饰的 , 对自己类的一个引用 。
在编写程序的时候 , 如果我们没有编写拷贝构造函数 , 那么编译器会为我们自动生成一个拷贝构造函数 。
下面看一下最简单的构造函数使用吧(使用默认构造函数)
#include
我们自己编写一个简单的拷贝构造函数:
#include
结果:
文章插图
什么情况下会调用拷贝构造函数?
主要有以下几方面:
- 对象以值作为函数参数传递 代码演示: #include
using namespace std;class CTest{public: CTest(int num) { nNum = num; } CTest(const CTestcout<<"call me CTest"< nNum; } ~CTest(){}private:int nNum;};void g_Fun(CTest C){cout<<"C:nNum"< - 一个对象初始化另外一个对象 例子:(开始的案例) int main(){ CTest A; CTest B = A;return 0;}
比如:
#include using namespace std;class CTest{public:CTest(int num){nNum = num;}CTest(const CTestcout<<"call me CTest"<nNum;}~CTest(){}private:int nNum;};CTest g_fun(){CTest tmp(0);return tmp;}int main(){g_fun();return 0;}
这种形式的调用拷贝构造函数 , 根据编译器不同就会被优化 , 经过测试windows 环境下vs调式是会调用拷贝构造函数的 , 但是在linux下g++编译后 , 就进行了优化 , 直接通过堆栈返回对象 , 少调用一次拷贝构造函数 。三、禁用拷贝构造函数上面我们回顾了拷贝构造函数的概念以及会调用拷贝构造函数的场景 , 感觉并没有异常发生 , 一切都函数那么友好 , 那么顺利 , 无论使用我们编写的构造函数还是使用默认拷贝构造函数 , 那么我们看一个例子 , 也许大家会有一些思考:
看下这个案例:
#include using namespace std;class CTest{public:CTest(string arg):name(arg),pStr(new char[10]){}~CTest(){delete pStr;}private:string name;char *pStr;};int main(){CTest C("test");CTest A = C;return 0;}
先不要看答案 , 大家可以思考下~文章插图
我们可以编译运行下 , 会出现什么现象:
root@iZuf67on1pthsuih96udyfZ:~/GDB/20201014# g++ -std=c++11 CopyConstruct.cpp root@iZuf67on1pthsuih96udyfZ:~/GDB/20201014# ./a.out *** Error in `./a.out': double free or corruption (fasttop): 0x000000000136ac20 ***======= Backtrace: =========/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fb1f13b97e5]/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fb1f13c237a]/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fb1f13c653c]./a.out[0x400caa]./a.out[0x400b7a]/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fb1f1362830]./a.out[0x400a19]======= Memory map: ========00400000-00401000 r-xp 00000000 fd:01 131851/root/GDB/20201014/a.out00601000-00602000 r--p 00001000 fd:01 131851/root/GDB/20201014/a.out00602000-00603000 rw-p 00002000 fd:01 131851/root/GDB/20201014/a.out01359000-0138b000 rw-p 00000000 00:00 0[heap]7fb1ec000000-7fb1ec021000 rw-p 00000000 00:00 0 7fb1ec021000-7fb1f0000000 ---p 00000000 00:00 0 7fb1f1039000-7fb1f1141000 r-xp 00000000 fd:01 925468/lib/x86_64-linux-gnu/libm-2.23.so7fb1f1141000-7fb1f1340000 ---p 00108000 fd:01 925468/lib/x86_64-linux-gnu/libm-2.23.so7fb1f1340000-7fb1f1341000 r--p 00107000 fd:01 925468/lib/x86_64-linux-gnu/libm-2.23.so7fb1f1341000-7fb1f1342000 rw-p 00108000 fd:01 925468/lib/x86_64-linux-gnu/libm-2.23.so7fb1f1342000-7fb1f1502000 r-xp 00000000 fd:01 925465/lib/x86_64-linux-gnu/libc-2.23.so7fb1f1502000-7fb1f1702000 ---p 001c0000 fd:01 925465/lib/x86_64-linux-gnu/libc-2.23.so7fb1f1702000-7fb1f1706000 r--p 001c0000 fd:01 925465/lib/x86_64-linux-gnu/libc-2.23.so7fb1f1706000-7fb1f1708000 rw-p 001c4000 fd:01 925465/lib/x86_64-linux-gnu/libc-2.23.so7fb1f1708000-7fb1f170c000 rw-p 00000000 00:00 0 7fb1f170c000-7fb1f1722000 r-xp 00000000 fd:01 918031/lib/x86_64-linux-gnu/libgcc_s.so.17fb1f1722000-7fb1f1921000 ---p 00016000 fd:01 918031/lib/x86_64-linux-gnu/libgcc_s.so.17fb1f1921000-7fb1f1922000 rw-p 00015000 fd:01 918031/lib/x86_64-linux-gnu/libgcc_s.so.17fb1f1922000-7fb1f1a94000 r-xp 00000000 fd:01 265161/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.217fb1f1a94000-7fb1f1c94000 ---p 00172000 fd:01 265161/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.217fb1f1c94000-7fb1f1c9e000 r--p 00172000 fd:01 265161/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.217fb1f1c9e000-7fb1f1ca0000 rw-p 0017c000 fd:01 265161/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.217fb1f1ca0000-7fb1f1ca4000 rw-p 00000000 00:00 0 7fb1f1ca4000-7fb1f1cca000 r-xp 00000000 fd:01 925451/lib/x86_64-linux-gnu/ld-2.23.so7fb1f1eb3000-7fb1f1eb9000 rw-p 00000000 00:00 0 7fb1f1ec8000-7fb1f1ec9000 rw-p 00000000 00:00 0 7fb1f1ec9000-7fb1f1eca000 r--p 00025000 fd:01 925451/lib/x86_64-linux-gnu/ld-2.23.so7fb1f1eca000-7fb1f1ecb000 rw-p 00026000 fd:01 925451/lib/x86_64-linux-gnu/ld-2.23.so7fb1f1ecb000-7fb1f1ecc000 rw-p 00000000 00:00 0 7ffdd4d0a000-7ffdd4d2b000 rw-p 00000000 00:00 0[stack]7ffdd4def000-7ffdd4df2000 r--p 00000000 00:00 0[vvar]7ffdd4df2000-7ffdd4df4000 r-xp 00000000 00:00 0[vdso]ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0[vsyscall]Abortedroot@iZuf67on1pthsuih96udyfZ:~/GDB/20201014#
- 打压|英方打压升级,禁止电信运营商,安装新的华为设备
- 国家网信办公开征求意见!禁止38类App超范围收集用户个人信息
- 机制|反马赛克机制问世,这种软件应该被禁止吗
- 零基础小白Python入门必看:通俗易懂,搞定深浅拷贝
- 关于Netty ByteBuf 的零拷贝
- 禁止生产和销售|明确了,我省马上全面禁用!
- SpringBoot构造流程源码分析:Web应用类型推断
- 构造流程源码分析:ApplicationListener加载
- 奖销售|新规明确禁止网购「忽悠式打折」:12 月起正式实施
- 排除华为或损失594亿!英国却宣布:明年9月起禁止安装华为5G设备