我一直被告知将临时实例传递给按引用传递函数是不安全的,我对下面的问题感到困惑,请你们为我解释一下。
#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++ 的方式。
如果有人能给我一些启发,我将不胜感激。
最佳答案
这就是 C++ 的工作方式。引用标准:
A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call
因此,由表达式 a + c
创建的类 Complex
的临时实例保证在 结束后 被销毁>operator=
调用。
关于c++ - 我应该在 operator= 中使用 pass-by-const-reference 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34526104/