2013-05-04 19 views
7

Sadece rvalue referansını anladığımı düşündüğümde, bu problemle karşılaştım. Kod muhtemelen gereksiz uzun, ama fikir oldukça basit. Main() işlevi ve returnRValueRef() işlevi vardır.Yeniden referans referansı nasıl çalışır?

#include <iostream> 

#define NV(x) "[" << #x << "=" << (x) << "]" 
#define log(x) cout << __FILE__ << ":" << __LINE__ << " " << x << endl 

using namespace std; 

class AClass { 
public: 
    int a_; 

    AClass() : a_(0) { 
    log("inside default constructor"); 
    } 
    AClass(int aa) : a_(aa) { 
    log("inside constructor"); 
    } 
    int getInt() const { 
    return a_; 
    } 
    void setInt(int a) { 
    a_ = a; 
    } 

    AClass(AClass const & other) : a_(other.a_) { 
    log("inside copy constructor"); 
    } 

    AClass & operator=(AClass const & rhs) { 
    log("inside assignment operator" << "left value" << NV(a_) << "right value" << NV(rhs.a_)); 
    a_ = rhs.a_; 
    return *this; 
    } 

    AClass & operator=(AClass && rhs) { 
    log("inside assignment operator (rvalue ref)" << "left" << NV(a_) << "right" << NV(rhs.a_)); 
    a_ = rhs.a_; 
    return *this; 
    } 
}; 

AClass && returnRValueRef() { 
    AClass a1(4); 
    return move(a1); 
} 

int main() { 
    AClass a; 
    a = returnRValueRef(); 
} 

Tamam, ilk baskı için bu kodu beklenebilir sonra (a1 için) (a için), sonra "kurucu içinde" ve atama operatörü mesaj "varsayılan kurucu içinde" rhs.a_ ile = 4. Ama çıkış

testcpp/return_rvalue_ref.cpp:14 inside default constructor 
testcpp/return_rvalue_ref.cpp:17 inside constructor 
testcpp/return_rvalue_ref.cpp:39 inside assignment operator (rvalue ref)left[a_=0]right[rhs.a_=0] 

birileri çıktı baskılar right[rhs.a_=0] yerine right[rhs.a_=4] yılında neden son satırı açıklayabilir mi? Move() 'in, içeriğini değiştirmeden sadece değerlerini rengin haline getirdiğini düşündüm. Ama açıkça bir şey eksik.

Yardımlarınız için teşekkürler çok teşekkürler. :-)

Düzenleme: Sanırım neler olabileceğini biliyorum. a1 için returnRValueRef() işlevinin kapsam dışı kaldığında çağrılması çağrılan (rengin değerine dönüştürülse bile) ve a1 için bellek konumu (veya bunun için referans değeri) undefined içeriyor! Olan şeyin olup olmadığından emin değilim, ama mantıklı görünüyor.

cevap

18

Bir referans referans hala referanstır. Sizin durumunuzda, tahrip edilmiş yerel değişkeni referans alıyorsunuz. Bu nedenle üyelere erişmek için tanımlanmamış bir davranıştır. Ne yapmak istediğiniz nesneyi döndürmektir:

AClass returnRValueRef() { 
    AClass a1(4); 
    return move(a1); 
} 

Ancak bir hamle yerel değişkenle otomatik olarak gerçekleşir, bu nedenle gerçekten sadece bunu yapmak gerekir: Yorumlarınız için

AClass returnRValueRef() { 
    AClass a1(4); 
    return a1; 
} 
+0

teşekkür ederiz. Yorumunuzu eklerken, aynı zamanda soruyu da düzenledim ve söylediğiniz şeyin problem olduğunu düşünüyorum. Teşekkürler. (Özür dilerim, cevabınızı fazla puan alamıyorum, çok az puan.) –

+0

@YogeshwerSharma: Sadece bir kabul harika olurdu, teşekkürler! –

+0

rvalue referans ile dönüşün faydalı olduğu bir örnek var mı? Olmuyor mu? :( –

İlgili konular