[英]Member vs non-member functions, return copy or reference?
对于什么样的返回类型成员函数和非成员函数应该有什么“规则”?
我正在构建一个复杂类,我认为成员函数将是返回类型引用,而非成员将是副本。 这个对吗?
Complex.h供参考:
#include <iostream>
#include <string>
#ifndef COMPLEX_H
#define COMPLEX_H
class Complex {
public:
double real;
double imaginary;
Complex();
Complex(const double real);
Complex(const double real, const double imaginary);
Complex(const Complex &rhs);
Complex& operator *= (const Complex&);
Complex& operator += (const Complex&);
Complex& operator /= (const Complex&);
Complex& operator -= (const Complex&);
Complex& operator = (const Complex&);
};
class Complex;
double abs(const Complex& c);
Complex operator * (const Complex& c1, const Complex& c2);
Complex operator / (const Complex& c1, const Complex& c2);
Complex operator + (const Complex& c1, const Complex& c2);
Complex operator - (const Complex& c1, const Complex& c2);
bool operator == (const Complex& c1, const Complex& c2);
bool operator != (const Complex& c1, const Complex& c2);
std::istream& operator >> (std::istream& in, Complex& c);
std::ostream& operator << (std::ostream& out, const Complex& c);
Complex operator ""_i(long double arg);
Complex operator ""_i(unsigned long long arg);
#endif
并不是会员还是非会员。 您在成员函数中返回了引用,因为它们实际上修改了this
值。
考虑以下代码:
Complex c1, c2, c3;
// ...
(c3 *= c2) += c1;
在这里将计算c3 *= c2
,然后将结果与c1
作为参数调用operator+=
。 如果您返回一个副本而不是c3 *= c2
的引用,则下一个应用的operator+=
将修改此返回的副本,而不是c3
,这不是期望的。
请注意,您也可以将其他运算符声明为成员函数,只是为了表明引用vs复制与成员vs非成员无关:
class Complex {
// ...
Complex& operator *= (const Complex&);
Complex& operator += (const Complex&);
Complex& operator /= (const Complex&);
Complex& operator -= (const Complex&);
Complex& operator = (const Complex&);
Complex operator * (const Complex& c2);
Complex operator / (const Complex& c2);
Complex operator + (const Complex& c2);
Complex operator - (const Complex& c2);
};
致电运营商时,您必须查看对结果的期望。
例如,如果您使用运算符*,则可能会希望
//Some Complex instances c1 and c2 already created
Complex c3 = c1 * c2;
您不希望修改c1或c2。 所以这里的副本很好。
但是,如果您使用运算符* =,则期望结果会修改在其上调用了运算符的Complex实例。 因此,这里引用比较好,因为您将避免使用复制构造函数和析构函数。
因此,您给出的示例是可以的。
就像我上面提到的那样,重要的问题不是这是成员还是非成员,而是返回的值是否是新实例。
任何更改对象本身的操作(例如++,+ =,-=,...)都应返回对该对象的引用。 另一方面,任何导致另一个对象的操作(如二进制+,-等)都必须创建一个新对象,因为绝不能更改原始操作数。
此外,您可以让某些二进制运算符成为成员(例如,complex + int),而其他二进制运算符必须在类外部定义(例如,int + complex)。 当然,您希望这两个操作具有相同的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.