我在c ++的很多例子中都看到,运算符重载作为参数获取了通过引用传递的类实例,或者如果它返回一个类实例,它也会通过引用返回它。是否有任何理由为什么人们选择通过引用传递它而传递指针/按值也会起作用? 一个例子:
Class MyClass
{
public:
int m_num;
MyClass() { m_num = 1;}
const MyClass operator+(const MyClass& mcls)
{
MyClass temp;
temp = m_num + mcls.m_num;
return temp;
}
}
假设我们重载=运算符。
所以以我编写的代码为例,通过引用向运算符+重载函数发送参数,并且不通过引用返回MyClass的实例也可以工作但我在很多例子中看到它传递并通过引用返回而且我想知道这背后是否存在某种原因,或者它只是某种类型的约定或者可能是偏好?
答案 0 :(得分:1)
如果您的实际问题是关于通过const引用传递,请参阅Why pass by const reference instead of by value?,否则请继续阅读。
你不应该return a reference to a local variable。局部变量超出范围,留下对垃圾的引用。 operator+
状态const MyClass operator+(const MyClass& mcls) const
{
MyClass temp = *this;
temp.m_num += mcls.m_num;
return temp;
}
不应该修改任何操作数并从两个参数中返回一个新值。
operator=
出于这个原因,重要的是你要复印一份。
另一方面,关于 MyClass& MyClass::operator=(const MyClass &rhs) {
// Check for self-assignment!
if (this == &rhs) // Same object?
return *this; // Yes, so skip assignment, and just return *this.
... // Deallocate, allocate new space, copy values...
return *this;
}
,您确实想要返回引用,因为它是C++ operator overloading guidelines。例如:
rhs
您想将*this
复制到{{1}}并返回参考:
[...]支持安全合理的操作员链接。 (通过返回*这样做。)
答案 1 :(得分:1)
如果您的职能是:
MyClass operator+(const MyClass *mcls)
然后代码a + b
将无法编译。你必须写a + &b
这太可怕了。
将运营商设为:
是有效的MyClass operator+(MyClass mcls)
从概念上讲,此代码会创建mcls
的额外副本,因为它是按值传递的。如果这个副本实际上可以移出,或者省略或者其他的优化,那么这是一个很好的风格。否则,const MyClass &
版本是一个很好的优化(有时是一个不成熟的版本!),以避免这种可能的额外副本。
请注意,这两个都应该是const
(即函数 - 而不是返回值),因为它们不会修改*this
。并且operator+
被认为是非成员函数的更好的风格
operator+
不应返回引用的原因是人们期望+
接受两个输入并生成新输出。如果代码为c = a + b;
,那么我们希望a
保持不变。你必须在一个保存总和的地方创建一个新对象,并返回它。当我们按值返回时,这是一个临时对象,通常编译器会忽略它并将结果直接写入c
。
operator+=
修改*this
并返回对*this
的引用是正确的。实现operator+
的一种好方法实际上就是在第一个操作数上调用operator+=
(当按值传递时)。
答案 2 :(得分:1)
严格地说,不需要通过引用或通过常量引用进行传递:代码将使用值传递。但是,对于大多数效率低下的运算符来说,因为按值传递需要复制整个对象 - 这是您通过引用传递时要避免的。
返回值也是如此:通常,您应该按值返回。但是,此规则有一个值得注意的例外:所有复合赋值运算符都需要通过引用返回,因为它们返回(*this)
。
使用指针而不是引用是不可能的,但出于不同的原因:C ++要求运算符按类型与特定签名兼容;引用与相应类型的值类型兼容,但指针不兼容。如果定义了一个带指针的运算符的重载,那么在处理值时C ++就不会使用你的运算符。