c++中有些重载运算符要返回引用的原因是:允许进行连续赋值;防止返回对象的时候调用拷贝构造函数和析构函数导致不必要的开销,降低赋值运算符的效率。
一、c++中有些重载运算符要返回引用的原因
允许进行连续赋值;防止返回对象的时候调用拷贝构造函数和析构函数导致不必要的开销,降低赋值运算符的效率。(返回对象也可以进行连续赋值(常规的情况,如a = b = c,而不是(a = b) = c))
对于第二点原因:如果用”值传递“的方式,虽然功能仍然正确,但由于return语句要把*this拷贝到保存返回值的外部存储单元之中,增加了不必要的开销,会降低赋值函数的效率。
场景:
需要返回对象引用或者返回对象(效率没有返回引用高),需要实现连续赋值,使重载的运算符更符合C++本身的运算符语意,如连续赋值 = += -= *= 、=,<<输出流
关于赋值 =,我们知道赋值=有连续等于的特性
1 int x,y,z;
2 x=y=z=15;
同样有趣的是,赋值采用的是右结合律,所以上述连锁赋值被解析为:
1 x=(y=(z=15));//赋值连锁形式
这里15先被赋值给z,然后其结果(更新后的z)再被赋值给y,然后其结果(更新后的y)再被赋值给x。
为了实现”连锁赋值“,赋值操作符号返回一个reference(引用)指向操作符号的左侧实参(而事实上重载运算符的左侧实参就是调用对象本身,比如= += -=等),这是你为classes实现赋值操作符时应该遵循的协议:这个协议不仅仅适用于以上的标准赋值形式,也适用于所有赋值运算。
复制代码
1 class Widght{
2 public:
3 …..
4 Widget& operator=(cosnt Widget& rhs)
5 {
6 …
7 return* this;
8 }
9 Widget& operator+=(cosnt Widget& rhs)
10 {
11 …
12 return* this;
13 }
14
15 Widget& operator-=(cosnt Widget& rhs)
16 {
17 …
18 return* this;
19 }
20
21 Widget& operator*=(cosnt Widget& rhs)
22 {
23 …
24 return* this;
25 }
26
27 Widget& operator/=(cosnt Widget& rhs)
28 {
29 …
30 return* this;
31 }
32 …
33 };
注意,这只是个协议,并无强制性,如果不遵循它,代码一样可以通过编译,然而这份协议被所有内置类型和标准程序库提供的类型入string,vector,complex,std::trl::shared_ptr或者即将提供的类型共同遵守。
延伸阅读:
二、内存池机制
在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
内存池概念
内存池的概念就是预先在内存中申请一定数量的,大小相等的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片,提升效率。内存池的实现方式有很多,性能和适用范围也不一样。
特性
Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的 malloc。
对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。