2015-12-30 57 views
3

我總是被告知將一個臨時實例傳遞給引用函數是不安全的,我對以下問題感到困惑,請你們爲我解釋一下。我應該在operator =中使用pass-by-const-reference嗎?

#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將創建類複合物,其將由const引用被傳遞到函數operator=的一個臨時的實例。在執行operator=之前是否有任何可能由a + c創建的臨時實例被破壞,導致operator=函數失敗? 我編譯此程序gcc4.4.7,它打印此:

enter image description here

看來,臨時實例是operator=後破壞。我仍然對這個結果感到困惑,不知道這是編譯器優化的結果還是C++的結果。 如果有人能夠啓發我,我將非常感激。

回答

4

這就是C++的工作方式。引用標準:

在一個函數調用 綁定到一個基準參數的臨時對象,持續直到含有 呼叫

[12.2/5.1]

所以臨時全表達的完成由a + c表達式創建的類Complex的實例保證被銷燬結束後operator= c所有。

+0

謝謝,這真的很有幫助。 –