使用运算符重载表单

时间:2015-12-15 07:16:01

标签: c++ oop operator-overloading

我想知道c ++中运算符重载下面的形式如:

ClassName & operator+(ClassName &other)
ClassName operator+(ClassName &other)
Classname operator+(const ClassName &other)
Classname operator+(const Classname other)
Classname operator+(Classname other)

使用有什么区别??

2 个答案:

答案 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可能是你最好的选择。