class Rational { public: Rational(int numerator = 0, int denominator = 1) : n(numerator), d(denominator) { printf("Rational Constructor\n"); } ~Rational() { printf("Rational Destructor\n"); } Rational(const Rational& rhs) { this->d = rhs.d; this->n = rhs.n; printf("Rational Copy Constructor\n"); } private: int n, d; friend const Rational operator*(const Rational& lhs, const Rational& rhs); };
Rational的*运算符可以这样重载:
const Rational operator*(const Rational& lhs, const Rational& rhs) { Rational tmp(lhs.n * rhs.n, lhs.d * rhs.d); return tmp; }
但是不可以这样重载:【区别在于一个&】
const Rational& operator*(const Rational& lhs, const Rational& rhs) { Rational tmp(lhs.n * rhs.n, lhs.d * rhs.d); return tmp; }
当这样去使用:
Rational x(1, 2), y(2, 3); Rational z = x * y;
第一种方法可以得到正确的结果,因为会调用Rational的拷贝构造函数将tmp赋给z,但是第二种方法返回的是tmp的引用,在函数退出前,tmp就被销毁了,所以这样做是不对的。
不过,第一种方法虽然功能上没有问题,但是效率上有所欠缺,因为调用了三次构造函数,一次复制构造函数,一次析构函数
Rational Constructor Rational Constructor Rational Constructor Rational Copy Constructor Rational Destructor
可以进行返回值优化如下:
const Rational operator*(const Rational& lhs, const Rational& rhs) { return Rational(lhs.n * rhs.n, lhs.d * rhs.d); }
Rational Constructor Rational Constructor Rational Constructor
优化之后少调用了一次复制构造函数和析构函数
完整代码如下:
#include <stdio.h> class Rational { public: Rational(int numerator = 0, int denominator = 1) : n(numerator), d(denominator) { printf("Rational Constructor\n"); } ~Rational() { printf("Rational Destructor\n"); } Rational(const Rational& rhs) { this->d = rhs.d; this->n = rhs.n; printf("Rational Copy Constructor\n"); } private: int n, d; friend const Rational operator*(const Rational& lhs, const Rational& rhs); }; const Rational operator*(const Rational& lhs, const Rational& rhs) { return Rational(lhs.n * rhs.n, lhs.d * rhs.d); } int main() { Rational x(1, 2), y(2, 3); Rational z = x * y; return 0; }