我一直被告知将一个临时实例传递给一个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编译了这个程序,它打印了这个:
operator=
之后,临时实例似乎被破坏了。我仍然对这个结果感到困惑,不知道这是编译器优化的结果还是C ++的结果。
如果有人能够启发我,我将非常感激。
答案 0 :(得分:4)
这是C ++的工作方式。引用标准:
绑定到函数调用中的引用参数的临时对象 一直持续到包含完整表达式的完整表达式 调用
因此,Complex
表达式a + c
创建的临时实例保证在<{strong> operator=
调用结束后被销毁。