![68befa2f8ff3253b9e40a6a06bb44f1d.png](https://i-blog.csdnimg.cn/blog_migrate/c77e848b3bd861d99a770ac5ec4670c0.png)
在最近的事例中,我发现,对于构造器出现了很多知识点。因此这一部分还不能够跳过去。
一、运算符重载[1]
- 函数重载:多次调用同名函数、传参不同。从而不必为不同名字的变量重写函数。
- 我们能够对于不同类型的数据,采取运算符重载。
1、运算符
int
2、运算符重载的限制
- 不能够被重载的运算符:条件(?),sizeof,scope(::),成员选择(.),成员指针选择(.*),casting operator。
- 只能够重载存在的运算符,不能够创造新的运算符。
二、通过友元函数重载数学运算符[2]
1、例子
#include
2、同一个类中存在不同类型的运算符
#include
三、使用普通的函数(normal function)进行运算符重载[3]
- 如果不需要访问私有成员变量进行运算符重载,那么能够通过普通函数定义。
#include
四、重载I/O运算符[4]
- 如果类中含有多个成员变量,那么如何方便的将它们print?
1、重载<<
friend
- return类型是ostream。
- 同时注意,我们传入的第一个参数是reference,不仅仅防止ostream被copy,同时能允许我们将output命令符锁在一起,cout << c1 << c2 << endl。
2、重载>>
如果c1中有3个成员变量,那么一次性输入3个参数的方法:
friend
五、通过成员函数(member function)重载运算符[5]
例子:
#include
和友元函数相比,成员函数的运算符重载只有一个参数。c1看起来变成了前缀。而这里隐藏了*this,即c1.operator+(2)实际上是operator(&c1, 2)。
- 使用范围
- 赋值=,偏且[],调用函数(),成员选择->,这几个操作符必须要作为成员函数。
- 一元运算符也通过成员函数重载。
- 如果二元运算中,运算符左侧的值会变化,那么通过成员函数进行重载运算符。
- 不适用成员函数重载的情况
- I/O操作符<< >>不能够作为成员函数,只能够作为友元函数。
- 二元运算中,运算符左侧的值不会变化,那么不用通过成员函数重载。
六、一元运算符重载[6]
- 取正数(+),取负数(-),逻辑否(!)是一元运算符。必须通过成员函数重载。
- 例子
#include
- 例子,逻辑否(!)
#include
七、重载比较运算符[7]
friend
八、重载()[8]——成员函数重载
const
例子
#include
结果
This is no const.
This is void operator.
This is no const.
0
九、copy constructor[9]
是的,它又来了。看看http://learncpp.com在此部分怎么讲解。
- copy constructor:构造器的特殊类型,通过复制现存对象的副本,创建新的对象。
- 即便在C++中不定义copy constructor,依然能够像默认构造器(implicitly)运行。
- 最好是explicitly定义:
#include
结果
This is copy.
5/3
十、重载赋值运算(=)[10]
- 将当前的对象复制给另一个对象。
- Assignment vs Copy constructor
- 基本一致。但是copy constructor需要初始化对象,而赋值运算符是替代了现存对象的内容。
- 如果在复制之前,需要创建新对象,那么使用copy constructor;
- 如果在复制之前,不必创建新对象,那么使用assignment。
- 重载
#include
结果
This
十一、Shallow VS Deep copy[11]
1、浅复制(shallow copy)
- copy constructor和assignment operator都是成员之间(memberwise copy)的复制(shallow copy)——复制类的每个成员。
- 面对动态分配内存的问题(dynamically allocated memory),浅复制将会陷入麻烦。因为,指针的浅复制返回的是该指针地址的副本——压根没有对副本分配新的空间。
例子
#include
如果通过浅复制(copy constructor),意味着将指向同一个对象。实际上,s2.m_datah和s1.m_data是同一个地址;同时,副本s2在走出花括号的时候被销毁。
2、深复制(deep copy)
- 解决之道:对于非空指针,进行深复制——给副本分配地址,从而副本和source在不同的内存区域。两者将不会相互影响。
- 修改
class
参考
- ^https://www.learncpp.com/cpp-tutorial/91-introduction-to-operator-overloading/
- ^https://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators-using-friend-functions/
- ^https://www.learncpp.com/cpp-tutorial/9-2a-overloading-operators-using-normal-functions/
- ^https://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/
- ^https://www.learncpp.com/cpp-tutorial/94-overloading-operators-using-member-functions/
- ^https://www.learncpp.com/cpp-tutorial/95-overloading-unary-operators/
- ^https://www.learncpp.com/cpp-tutorial/96-overloading-the-comparison-operators/
- ^https://www.learncpp.com/cpp-tutorial/99-overloading-the-parenthesis-operator/
- ^https://www.learncpp.com/cpp-tutorial/911-the-copy-constructor/
- ^https://www.learncpp.com/cpp-tutorial/9-14-overloading-the-assignment-operator/
- ^https://www.learncpp.com/cpp-tutorial/915-shallow-vs-deep-copying/