拷贝构造函数、赋值函数浅析
来源:互联网 发布:can数据帧的格式结构 编辑:程序博客网 时间:2024/05/22 01:59
注:以下为阅读网络上以及书上的相关内容后,自己总结的结果。因参考资料众多,无法附上链接,在此抱歉。
一个类A,如果什么都不编写,c++编译器将自动为A产生四个默认的函数(实际上还有两个,在此不列出),即:
对于构造函数和析构函数我们都了解。那么拷贝构造函数和赋值函数是什么呢?
一、基本概念
1、拷贝构造函数:(也叫复制构造函数)
拷贝构造函数是C++独有的,它是一种特殊的构造函数,简单地说,是用来初始化另一个类对象的函数。
当没有重载拷贝构造函数时,即没有在类里面重写拷贝构造函数时,通过默认拷贝构造函数来创建一个对象:
class A {public: A(A& x) // 第一种形式 A(const A& x) // 第二种形式 A(A& x, int a = 0, int b = 1…) // 第三种形式};A a;A b(a); // 这里b对象还没有存在,是用 a 对象来构造和初始化 b 的! // 第一种写法A b=a; // 第二种写法
2、赋值函数:
当一个类的对象向该类的另一个对象赋值时,就会用到该类的赋值函数。
当没有重载赋值函数时,通过默认赋值函数来进行赋值操作:
(赋值函数本质是赋值操作符,重载赋值函数即重写赋值操作符)
class A { //……};A a;A b; // 这里b对象是已经存在的,是用 a 对象来赋值给 b 的!b=a;
二、为何要自己重写
既然系统能自动生成这些函数,为什么还需要自定义?
最重要的原因是:默认的拷贝构造函数 和 默认的赋值函数 均采用 位拷贝 而非 值拷贝。
位拷贝 拷贝的是地址,而 值拷贝 拷贝的是内容。
位拷贝 == 浅拷贝 == 按位拷贝
值拷贝==深拷贝 == 按值拷贝
浅拷贝会发生的问题:
- a原来的内存区域未释放,造成内存泄露。
- a和b指向同一块区域,任何一方改变,会影响到另一方。
- 当对象释放时,b会释放掉两次。
因此:当类中还有指针变量时,拷贝构造函数 和 赋值函数 就隐含了错误。此时需要自己定义。
具体解释网上有一位解释的非常好,找时间把地址贴过来。
不理解也没关系,只要记住一件事就好:必须要重写!
如果不想写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的默认的函数,最简单的办法是将拷贝构造函数和赋值函数声明为私有函数:
class A{ private: A(const A& a); // 私有拷贝构造函数 A& operate=(const A& a); // 私有赋值函数}
三、什么情况下使用
什么情况用到拷贝构造函数:
1)一个对象以值传递的方式传入函数体
2)一个对象以值传递的方式从函数返回
3)一个对象需要通过另一个对象进行初始化
class A {public: A(A& x) // 第一种形式};int Fun1(A x){ return x.a + x.b;}A Fun2(int a, int b){ A a(a, b); return a; }A c(10, 10);A d(c); // 情况1) -> 调用拷贝构造函数int e = Fun1(c); // 情况2) -> 调用拷贝构造函数A f = Fun2(11, 11); // 情况3) -> 调用拷贝构造函数
P.S.
赋值函数需要处理自我赋值的问题,因为自我赋值会出现指针指向一个已经释放的内存。(详见最后一个链接的文章)
例子:
String::String(const String &other){ cout << "自定义拷贝构造函数" << endl; int length = strlen(other.m_data); m_data = new char[length + 1]; strcpy(m_data, other.m_data);}String & String::operator=(const String &other){ cout << "自定义赋值函数" << endl; if (this == &other) //※ { return *this; } else { delete [] m_data; int length = strlen(other.m_data); m_data = new char[length + 1]; strcpy(m_data, other.m_data); return *this; }}
四、文章推荐
几篇我认为对我帮助很大的好文章:
C++类中拷贝构造函数详解
C++中构造函数,拷贝构造函数和赋值函数的区别和实现
对于拷贝构造函数和赋值构造函数的理解
复制构造函数 与 赋值函数 的区别
C++赋值函数详解
- 拷贝构造函数、赋值函数浅析
- C++构造函数、拷贝构造函数、赋值函数浅析
- 浅析C++ 中拷贝构造函数 与赋值构造函数
- 拷贝,赋值构造函数赋值
- 浅析类的 默认构造函数, 拷贝构造函数, 赋值拷贝函数“=”
- 浅析拷贝构造函数
- 赋值函数、拷贝构造函数
- 拷贝构造函数赋值函数
- 拷贝构造函数,赋值函数
- 构造函数 拷贝函数 赋值构造函数
- 构造函数 拷贝函数 赋值构造函数
- 构造函数、拷贝构造函数、赋值函数
- 拷贝构造函数 与 拷贝赋值函数
- 拷贝构造函数和拷贝赋值函数
- 构造函数,拷贝构造函数,析构函数,赋值运算符重载浅析
- 拷贝构造函数和赋值构造函数
- 拷贝构造函数与赋值构造函数
- 拷贝构造函数与赋值构造函数
- IO其他流--处理流保留数据+引用数据类型
- PostgreSQL备份与恢复示例
- 【安全牛学习笔记】离线密码破解、离线密码破解-Hashcat
- Linux中的输入输出管理及vim的简单操作
- LeetCode 135. Candy
- 拷贝构造函数、赋值函数浅析
- SSH 无法启动的原因分析及解决方法
- 使用commons-beanutils-1.8.3.jar提供的BeanUtils类快速封装属性时,遇到的错误
- LeakCanary使用(Android试手)
- Android Studio之maven Central,JCenter
- 【 Codeforces Round #367 (Div. 2) D】 Vasiliy's Multiset (Trie 按数位建字典树)
- 选择排序(简单选择排序--改进的简单选择排序--堆排序)
- post提交参数有Date类型,总是返回400格式错误
- 【学术】 一个博士的经历(小木虫精华帖,留着细细体会!)