我应该在operator =中使用pass-by-const-reference吗?

时间:2015-12-30 08:55:25

标签: c++

我一直被告知将一个临时实例传递给一个pass-by-reference-function是不安全的,我对下面的问题感到困惑,你能不能为我解释一下。

#include <iostream>
using namespace std;
int cnt = 0;
class Complex
{
public:
    //explicit 禁止double隐式转换为Complex
    explicit Complex(double real, double imaginary = 0)
        : real_ (real), imaginary_(imaginary)
    {
        id_ = cnt++;
        cout << "complex constructed id:" << id_ << endl;
    }

    //也可以explicit来禁止隐式调用拷贝构造函数
    Complex(const Complex& other): real_ (other.real_), imaginary_(other.imaginary_)
    {
        id_ = cnt++;
        cout << "complex copy constructed id:" << id_ << endl;
    }

    ~Complex()
    {
        cout << "complex destructed id:" << id_ << endl;
    }

    Complex& operator= (const Complex& rhs)
    {
        cout << "complex operator=" << endl;
        real_ = rhs.real_;
        imaginary_ = rhs.imaginary_;
        return *this;
    }

    //return-by-reference, pass-by-const-reference 
    Complex& operator+= (const Complex& other)
    {
        real_ += other.real_;
        imaginary_ += other.imaginary_;
        return *this;
    }

    //return-by-reference
    Complex& operator++()
    {
        ++real_;
        return *this;
    }

    //return-by-const-value是为了防止a++++的情况
    const Complex operator++(int)
    {
        Complex temp(*this);
    }

    ostream& Print(ostream& os) const
    {
        return os << "(" << real_ << "," << imaginary_ << ")";
    }

private:
    int id_;
    double real_;
    double imaginary_;

};

const Complex operator+ (const Complex& lhs, const Complex& rhs)
{
    cout << "complex operator+ " << endl;
    Complex ret(lhs);
    ret += rhs;
    return ret;
}

ostream& operator<< (ostream& os, const Complex& c)
{
    return c.Print(os);
}

int main()
{
    Complex a(1, 10);
    Complex b(2, 5);
    Complex c(3, 0);
    b = a + c;
    return 0;
}

代码a + c将创建一个Complex类的临时实例,它将由const引用传递给函数operator=。在执行a + c之前,operator=创建的临时实例是否有可能被破坏,导致operator=函数失败?   我用gcc4.4.7编译了这个程序,它打印了这个:

enter image description here

operator=之后,临时实例似乎被破坏了。我仍然对这个结果感到困惑,不知道这是编译器优化的结果还是C ++的结果。   如果有人能够启发我,我将非常感激。

1 个答案:

答案 0 :(得分:4)

这是C ++的工作方式。引用标准:

  

绑定到函数调用中的引用参数的临时对象   一直持续到包含完整表达式的完整表达式   调用

[12.2/5.1]

因此,Complex表达式a + c创建的临时实例保证在<{strong> operator=调用结束后被销毁。