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

标签 c++

我一直被告知将临时实例传递给按引用传递函数是不安全的,我对下面的问题感到困惑,请你们为我解释一下。

#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++ 的方式。 如果有人能给我一些启发,我将不胜感激。

最佳答案

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

A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call

[12.2/5.1]

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

关于c++ - 我应该在 operator= 中使用 pass-by-const-reference 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34526104/

相关文章:

c++ - 如何实现尺寸有限的 map

c++ - 为什么同一台服务器的两个版本表现不同?

c++ - new[] 如果元素默认构造函数可以抛出?

c++ - 在 C++ 中,我应该等多久直到套接字的发送缓冲区为空?

C++ : How to ensure that a class member variable is modifiable only within a certain method

javascript - 等号中的空格

C++整数溢出

c++ - 元组和可变参数模板,这是如何工作的?

c++ - 将 Mat 转换为不同类型的自身是否安全?

c++ - 模板成员变量