我想知道c ++中运算符重载下面的形式如:
ClassName & operator+(ClassName &other)
ClassName operator+(ClassName &other)
Classname operator+(const ClassName &other)
Classname operator+(const Classname other)
Classname operator+(Classname other)
使用有什么区别??
答案 0 :(得分:3)
仅供参考:所引用的运算符都不是正常运算符
实际上超载了!通常过载的那个更像是
这(假设它与ClassName
在同一名称空间中):
ClassName operator+ (ClassName const& op1, ClassName const& op2) {
ClassName rc(op1);
rc += op2;
return rc;
}
如何实施此运营商有一些变化。在
特别是第一个参数可以通过值传递以避免复制
在实施中:在某些情况下,副本可以省略。这个使用命名变量并按名称返回的特定实现旨在启用复制省略(正如@juanchopanza指出的那样,return ClassName(op1) += op2;
不允许复制副本以获得返回值。)
关于您的实际问题,区分是很重要的 引用和值之间:
当使用类似ClassName
的值时,传递给的对象
函数或从函数返回的函数是副本。上课的时候
问题是微不足道的,这是好的,但如果课程更多
复杂并为其成员分配内存可能有一些
创建实际副本的成本。另一方面,它在语义上是
经常需要使用副本。例如,添加的结果
通常是一个不同的对象,因此,需要是一个副本。
为了从一些成本中获取优势,编译器会尝试 尽可能难以避免复制。例如,返回时 局部变量复制在许多情况下被省略或对象是, 至少,移动(假设使用C ++ 11或更高版本并且该类具有 移动构造函数)。
使用ClassName&
或ClassName const&
等参考时,
实体实际上只是对象的名称。没有复制
但是某个对象需要存在于某处。 const
与?的存在
缺少const
只表示是否所有方法
可以调用const
方法或是否可以传递引用
需要另一个引用的地方:非const
引用可以
转换为const
参考但不反过来。
出于参数的目的,const
之间的关键区别
引用和非const
引用是临时对象
无法在 绑定到<{1}}引用时绑定到非const
引用
const
引用。
有了这个排序,这里是不同声明的贯穿
operator+()
:
ClassName & operator+(ClassName &other)
此声明将非const
引用作为参数并返回
非const
引用。对于论证,这意味着它不能
是一个临时的,但需要有一个名字。为了回报
表示返回的对象需要保持活动状态。通常是
另外创建一个新对象并尝试保持对象存活
一定不行。如果ClassName
复制真的很贵
您可能不想提供operator+()
,而只是提供
一个operatr+=()
,它在语义上产生与之相同的结果
operator+()
但是就地执行。
ClassName operator+(ClassName &other)
此声明具有参数的主要约束
非const
引用,即参数不能是临时的
对象但必须是左值,即某种方式
命名。但是,arguemnt不会被复制。
ClassName operator+(const ClassName &other)
此声明适用于临时工,是两种可能之一
成员operator+()
的样子如何。争论
仍然没有被复制,但因为它是[逻辑]不可变的临时
对象可以用作参数。
ClassName operator+(const ClassName other)
这将复制参数。出于声明的目的
const
将毫无意义,它实际上可能有所不同
相同功能的不同声明。当定义
使用此声明它意味着复制参数,即
operator+()
有一个本地版本但实际上无法更改此版本
复制。很可能它需要创建另一个副本来生成一个
结果。相应地,我认为用const
定义一个函数
value参数完全没有意义:如果你想要一个常量,请使用
const ClassName&
或ClassName const&
(这些是相同的;我这样做
更喜欢后一种符号,因为它会产生一致的位置。
ClassName operator+(ClassName other)
与之前的声明一样,这个复制了参数,但是
论证是可变的。假设oepration是可交换的,你可以
容易变异other
以产生返回值。但请注意,
复制other
将不会被删除(不允许编译器
删除复制功能参数)但它可以移动。假设
ClassName
要么便宜,要么以other
为基础
对于结果,这是另一个可能的候选人如何运营商
已定义。
答案 1 :(得分:1)
第一个返回一个引用,并引用一个引用 - 这意味着理论上你可以改变两个参数,并返回一个引用,也可以改变它。这通常不是你想要做的(2 + 3不返回5,可以重新分配到17)。
第二个是相同的,但没有返回参考。
第三个有const引用 - 一个无法修改的引用。这通常是你想要做的,因为你快速获得元素(你得到 元素),但你无法改变它(偶然或不是)。
第四个就像第三个,但你复制一个参数,并因某种原因使它成为const。这没什么意义。
最后一个只需要一份副本。
其中一些没有太大区别 - 如果你考虑operator+
必须做什么,其中一些没有意义;它们不同的区域主要是你如何得到论证 - 而且大多数时候,你想要快速得到它,所以const ClassName& other
可能是你最好的选择。