| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C++特殊成员函数(深拷贝和深赋值) -> 正文阅读 |
|
[C++知识库]C++特殊成员函数(深拷贝和深赋值) |
码文不易,觉得内容不错点个关注吧~ 在C++的类中有这么一些成员函数是自动定义的,具体如下所示: 1.默认构造函数 2.默认析构函数 3.复制构造函数(即拷贝构造函数) 4.赋值运算符 5.地址运算符 C++11提供了另外的两个特殊成员函数:移动构造函数和移动赋值运算符,在后讨论。 本文仅讨论1,3,4的问题 一.默认构造函数在不定义构造函数时,会自动定义一个默认构造函数。反之则不会定义。如果想在创建对象的时候不显式地初始化,就必须自己显式地定义默认构造函数。这种构造函数没有参数,有两种方式:1.不带任何参数的默认构造。2.带default值的有参构造函数。 注意:这两种定义不能同时存在,不然的话在用默认构造创建对象的时候会有二义性。
二.复制构造函数(拷贝构造函数)2.1何为拷贝构造函数,何时调用拷贝构造函数用于将一个对象复制到新建对象中。一言以蔽之,初始化过程中。 常见原型 Class_name(const Class_name &) 它接受一个指向类对象的常量作为参数,以下为调用拷贝构造函数的4种声明
2.2默认拷贝构造函数的功能与缺陷默认拷贝构造函数逐个复制非静态成员,复制的是成员的值。(这就是浅拷贝) 注意:静态成员不受影响,因为它们属于整个类,所有的对象都共享同一份,因此不会被操作。 为了说明浅拷贝的危害,下面举一个例子来说明。这是一个有缺陷的Stirng类的实现,因此将他命名为Stringbad。
接着我们在main函数中调用以下这个测试:
?1.我们先通过构造函数创建了两个对象a1,a2,在构造函数中我们每次都会让num_string这个值+1,因此为2,说明有两个对象了。 2.然后我们使用默认拷贝构造将a1拷贝给了copy_1,但是默认拷贝构造只是简单的将成员的值复制了一下而已,并没有使静态成员发生变化,因此我们的num_string还是2.(缺陷1) 3.由于对象的创建顺序是a1,a2,copy_1因此析构的顺序也应该是copy_1,a2,a1。我们观禅控制台的输出,1.发现先是ddd被delete了,这个是copy_1的成员变量str被delete了。2.接着是mmm,也正常地被析构了3.然后是a1的mmm,但是并没有正常地打印出内容这是为什么呢??因为浅拷贝只是简单的赋值而已,它将指向a1的str的指针直接拿给了copy_1,相当于这两个对象都指向了同一片区域,因此对copy的str删除,将使a1指向的str也没有了ps:就是同一个(缺陷2) 总结:1.不能拷贝静态变量 ?????????? 2.在存在指针的情况下,并没有给新对象独立的区域而是简单的赋值。 3.3解决方案:深拷贝 ?????????深拷贝就是在上述的缺陷中提出来的,代码实现如下。非常简单,就是将C++没有给我们考虑好的拷贝要素自己写好就OK了,这就是深拷贝,这样就是真正独立的一个对象了,并不依靠于别的对象。
?三.赋值运算符3.1赋值运算符的来由,我们为何能隐式构造现在我们来关注一下这个写法Stringbad copy_2 = initial; 显然这就是拷贝构造嘛,前面讲的隐式构造。但是!为什么这样是可以的呢?C语言没有类,当然不会支持它,C++为什么支持呢?其实这里是C++通过为我们类重载赋值运算符实现的,这种运算符的原型如下: ??????? Class_name & Class_name::operator=(const Class_name &); 那你可能会奇怪了,那我们直接重写一个赋值运算符就好了,不用写拷贝构造了,因为像Stringbad copy_2 = intial这样的写法,能够直接被匹配。 实际上初始化对象时并不一定会使用赋值运算符。 上述语句实现的时候可能会分两布处理该语句:1.使用拷贝构造函数创建一个临时变量2.通过=赋值重载复制到新对象中。 也就是说初始化总会调用靠背构造,而使用=运算符也允许调用赋值运算符。 3.2赋值的错误赋值的错误如下所示,a1用a2赋值了,从而先析构a2的时候str内容已经消失了,再析构a1的时候以及该地质以及没有内容了,会出现数据受损的危害。
3.3解决赋值问题(深赋值)与深拷贝一样,深赋值就是把浅操作的问题都弥补一下,但是是有所差别的需要注意如下: 1.由于目标对象可能引用了以前分配的数据,所以需要使用delete[]来释放这些数据防止内存泄漏。 2.函数应该避免赋给自己;否则在给对象重新赋值前会将该对象的内容删除。 3.函数返回一个指向调用对象类型的引用。
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:28:15- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |