2017-06-23 69 views
4

在我的項目中,大多數對象都是在競技場中創建的,並且可以保證它們在用戶會話期間存在。 所以這是相當安全的一些類,以便const引用作爲成員字段,例如:防止通過引用傳遞右值

class A { 
public: 
    A(const string& str) : str_(str) {} 

private: 
    const string& str_; 
}; 

但這裏有一個陷阱。錯誤有可能產生的A實例的方式如下:

A a("some temporal string object"); 

在該行的時間string對象已隱式創建和銷燬。那之後a存儲不正確的參考。

如何防止這種行爲?它會更好,如果它導致編譯錯誤...

+1

如果你的競技場剛分配的內存大塊它不應該難以檢查'this'是否屬於它,並在構造函數中添加相關的'assert'。另一種方法是將構造函數設爲私有,並提供一個使用舞臺來分配對象的工廠方法。這也具有在編譯時檢測到錯誤的優點。 –

+0

沒有等待,我現在意識到你想要爲任意類型工作,所以第二種方法是不可行的。 –

+0

@MatteoItalia,是的,類型不應該知道競技場的任何東西)而我寫的競技場只是爲了證明引用作爲成員字段。 – Alexey

回答

3

你只需要有一個重載比rvalues更好匹配,以便編譯器採取一個通過const&之一。

所以,暫時的更好匹配的&&const&,所以你只需要提供這樣一個構造函數和delete它:

class A { 
public: 
    A(const string& str) : str_(str) {} 
    A(string&&) = delete; // this constructor is a better match for rvalues 

private: 
    const string& str_; 
}; 
+0

不過,這對堆棧分配的對象沒有幫助。 –

+0

@MatteoItalia沒錯,但是唯一可行的解​​決方案就是不參考所有IMO。 – Rakete1111

+2

是的,可能是正確的解決方案將只是採取一些智能指針類對象,封裝了一個指針,只能通過競技場中產生。 –