2011-10-26 28 views
25

這是創建具有參考成員的作業操作員的有效方法嗎?具有參考成員的作業操作員

#include <new> 

struct A 
{ 
    int &ref; 
    A(int &Ref) : ref(Ref) { } 
    A(const A &second) : ref(second.ref) { } 
    A &operator =(const A &second) 
    { 
     if(this == &second) 
      return *this; 
     this->~A(); 
     new(this) A(second); 
     return *this; 
    } 
} 

這似乎編譯和運行良好,但與C++趨勢表面在不經意未定義的行爲,和所有的說,它是不可能的人,我認爲有一些疑難雜症我錯過了。我錯過了什麼嗎?

+0

順便說,參數爲'操作員='和拷貝構造應該是常量引用。 –

+1

正確性可能僅限於標準佈局類型,因爲虛擬'this'不需要是指向內存塊開始的指針。 –

+6

如果你需要這樣做,我會建議使用引用重新思考。 – bames53

回答

31

它在語法上是正確的。但是,如果新放置的放置最終會以不能破壞的對象結束。如果有人從你的班級派生出來,更不用說災難 。只是不要這樣做。

解決方案很簡單:如果課程需要支持作業,請不要使用任何參考成員 。我有很多類參考 參數,但將它們存儲爲指針,只要這個類可以支持 分配。類似:

struct A 
{ 
    int* myRef; 
    A(int& ref) : myRef(&ref) {} 
    // ... 
}; 
+0

+1,這就是我所做的。 – 2011-10-26 17:12:14

+0

我喜歡這個 - 簡單明瞭的解決方案! – aardvarkk

3

就我所知,你在技術上做了什麼正確的操作,但它會產生麻煩。例如,考慮從A派生類會發生什麼,因爲它的賦值操作符生成一個新對象(切片)。難道你不能把參考變成你班上的指針嗎?

除此之外,複製構造函數和賦值運算符通常採用const&的參數。

+0

這是如何產生麻煩的? –

1

你所做的是正確的,但它不是編寫複製賦值操作符的非常安全的方式。另外,您應該考慮使用指針成員而不是引用成員。

您應該使用Copy and Swap Idiom來實現它。它比你的實現具有至少三個優點。

+0

但是如何交換引用? –

+0

@ChristianRau:無論如何,你將會實現你自己的'swap'功能。 –

+0

是的,這可能需要交換引用。 –

2

另一種解決方案是使用的reference_wrapper類(在功能性報頭):

struct A 
{ 
    A(int& a) : a_(a) {} 
    A(const A& a) : a_(a.a_) {} 

    A& operator=(const A& a) 
    { 
     a_ = a.a_; 
     return *this; 
    } 

    void inc() const 
    { 
     ++a_; 
    } 

    std::reference_wrapper<int>a_; 

};