c++ 副本构造器
我们都知道两个指针指向同一个变量时如果一个指针被释放那么另一个就会出问题
为了说明问题我做了一个很恶心的小例子
class C { public :C(int v){ptrInt=new int;*ptrInt=v;valueInt = v;}~C(){}void DelIntV(){valueInt=0;delete ptrInt;}C(const C& c){}int * ptrInt;int valueInt; private:};int main() {C c1(2);C c2(3);c2=c1;std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;c1.DelIntV();std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;std::cin.get();return 0; }
这是把c1赋值给了c2后把指针ptrInt的值输出和valueInt输出,再把c1的指针给delete,valueInt赋值为0
再输出c2的ptrInt和valueInt就会发现指针有问题,看一下输出结果:
已经不对了吧。
为了解决这样的问题我第一个想到的就是重载操作符=
C& operator=(const C &c){if(this!=&c){delete ptrInt;ptrInt = new int;*ptrInt= *c.ptrInt;valueInt=c.valueInt;}return *this;}
完整代码
class C { public :C(int v){ptrInt=new int;*ptrInt=v;valueInt = v;}~C(){}void DelIntV(){valueInt=0;delete ptrInt;}C(const C& c){}int * ptrInt;int valueInt;C& operator=(const C &c){if(this!=&c){delete ptrInt;ptrInt = new int;*ptrInt= *c.ptrInt;valueInt=c.valueInt;}return *this;} private:};int main() {C c1(2);C c2(3);c2=c1;std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;c1.DelIntV();std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;std::cin.get();return 0; }
再看一下输出结果:
这下就正确了吧,但是如果 我们在main函数里做一个修改
int main() {C c1(2);C c2=c1;//这里直接赋值std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;c1.DelIntV();std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;std::cin.get();return 0; }
这样后错误就又和之前一样了,为什么呢,
编译器将在c类里找一个副本构造器(copy constructor)如果找不到它会自己创建一个,
即使我们对操作符=进行了重载也没有用,由编译器自己创建的副本构造器仍会以"逐们复制"
的方式把c1赋值给c2
这样我们还要重新实现这个副本构造器,
className(const className &cn);
我是这样做的
C(const C& c){*this=c;}
这里的=其实就是调用的重载的=方法
完整代码
class C { public :C(int v){ptrInt=new int;*ptrInt=v;valueInt = v;}~C(){}void DelIntV(){valueInt=0;delete ptrInt;}C(const C& c){*this=c;}int * ptrInt;int valueInt;C& operator=(const C &c){if(this!=&c){delete ptrInt;ptrInt = new int;*ptrInt= *c.ptrInt;valueInt=c.valueInt;}return *this;}private:};int main() {C c1(2);C c2=c1;//这里直接赋值std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;c1.DelIntV();std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl;std::cout<<"valueInt "<<c2.valueInt<<std::endl;std::cin.get();return 0; }
结果
c++ 副本构造器相关推荐
- 构造器和析构器 - C++快速入门15
构造器和析构器 让编程改变世界 Change the world by program 定义构造器 回顾:之前我们讨论了使用面向对象的编程技术开发程序最基本步骤: 定义一个有属性和方法的类(模板) 为 ...
- C++:随笔7---运算符重载
当我们进行a+b操作时,他返回的是a-b. 例子:实现复数的加法. //用C++类的方法实现复数加法 #include<string> #include<iostream>cl ...
- C++快速入门学习笔记(一)
一.C++语言与面向对象思想介绍 C++是一种语言,仅仅是它的语法.特性.标准类库就已经是一门非常高深的课程,所以在开始学习的时候,必项先要打好基础. C语言有一个优点,即它的速度可以很快.写出来的程 ...
- C++学习记录(B站小甲鱼C++快速入门视频)
文章目录 C++特点: 封装 抽象 继承 多态 从一个小程序开始 第二个小程序(IO) cin跟cout对象的多个方法 第三个小程序(File) 多种文件操作用or操作符`"|"` ...
- OpenCV3 和 Qt5 计算机视觉:6~10
原文:Computer Vision with OpenCV 3 and Qt5 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 计算机视觉 译文集],采用译后编辑(MT ...
- 最新《小甲鱼C++编程快速入门教程》
这套教程一共40讲,内容真心不错,其实大家看看目录也就能得出结论了 ===============课程目录=============== <鱼C论坛小甲鱼C++编程快速入门培训系列教程> ...
- OpenCV2 计算机视觉应用编程秘籍:1~5
原文:OpenCV2 Computer Vision Application Programming Cookbook 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 计 ...
- java集合之TreeMap 构造器 方法 比较器
java集合之TreeMap 基于红黑树(Red-Black tree)的 NavigableMap 实现. 映射根据其键的自然顺序进行排序,或者通过映射创建时提供的 Comparator 进行排序, ...
- 一文了解 Java 中的构造器
摘要:Java 也采用了构造器,并且还提供了一个垃圾收集器(garbage collector),当不再使用内存资源的时候,垃圾收集器会自动将其释放. 本文分享自华为云社区<一文带你了解 Jav ...
最新文章
- Unity提出ProtoRes模型:稀疏可变的输入也能构建完整人体姿态
- 【js】callback时代的变更
- Python 修改tuple元组提示:TypeError: ‘tuple‘ object does not support item assignment. 问题原因
- 使用easyui框架form控件,单选按钮radio或复选框checkbox样式问题
- JavaScript常用API总结
- Linkedln技术高管Jay Kreps:Lambda架构剖析
- table虚线边框_web前端工程师7天0基础到精通(TABLE+CSS制作《互联世纪网》)
- jQuery - Bootstrap 3 and Youtube in Modal
- 证券期货信息安全等级保护测评
- 关于《PHP任务学习》的说明
- ssh 连接保持不中断
- js简单实现切换图片上一张下一张功能
- 文章发送到多平台软件:融媒宝
- workstation服务丢失 共享打不开 0x80070035
- 软件项目经理应具备的素质和条件_一个合格的软件项目经理应该具备哪些条件?...
- 微信公众号开发C#系列-11、生成带参数二维码应用场景
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
- DSP28m35的IPC通讯编程经验
- 写给海布里之王—亨利
- 《Maven实战》(许晓斌)导读(读书笔记第二次读后感)
热门文章
- 安装fio命令linux,fio安装和使用方法
- linux 发生变更的文件夹,【Linux常识篇(3)】文件及文件夹的ctimeatimemtime的含义详解...
- 20200907:力扣203周周赛题解记录
- day02:关于惯性导航工具箱的学习与使用:use of the progen
- android网格布局间距,android – 删除回收站视图网格布局中的默认间距
- li鼠标悬浮手势样式
- 两日公开课:伯克利深度强化学习训练营 | 视频+PPT
- python获取指定日期的前N天日期和后N天日期
- Python将字符串转为字典最佳实践
- 【Part1】用JS写一个Blog(node + vue + mongoDB)