必须返回对象时,别妄想返回其reference 【Effective C++ 条款21】

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;
}

 

上一篇:你不知道的javascript (上卷) 笔记


下一篇:leetcode 692. 前K个高频单词 (百度)2021-08-03