2013-03-12 13 views
13

Kurucuları ve atama işlemlerinin C++ 11'de çalışma şeklini anlamaya çalışıyorum ama üst sınıflara delege etme konusunda sorun yaşıyorum.Yapıcıları ve devralmayı taşıyın

kodu: Ancak

class T0 
{ 
public: 
    T0() { puts("ctor 0"); } 
    ~T0() { puts("dtor 0"); } 
    T0(T0 const&) { puts("copy 0"); } 
    T0(T0&&) { puts("move 0"); } 
    T0& operator=(T0 const&) { puts("assign 0"); return *this; } 
    T0& operator=(T0&&) { puts("move assign 0"); return *this; } 
}; 

class T : public T0 
{ 
public: 
    T(): T0() { puts("ctor"); } 
    ~T() { puts("dtor"); } 
    T(T const& o): T0(o) { puts("copy"); } 
    T(T&& o): T0(o) { puts("move"); } 
    T& operator=(T const& o) { puts("assign"); return static_cast<T&>(T0::operator=(o)); } 
    T& operator=(T&& o) { puts("move assign"); return static_cast<T&>(T0::operator=(o)); } 
}; 

int main() 
{ 
    T t = std::move(T()); 
    return 0; 
} 

, ben derlemek ve VS2012 altında çalıştırmak, çıkış T0 üyelerinin lvalue versiyonları denir gösterir:

ctor 0 
ctor 
copy 0 <-- 
move <-- 
dtor 
dtor 0 
dtor 
dtor 0 

Benzer bir durum (ile biraz farklı bir test durumu) hareket atamaları ile gerçekleşir - T'nin hareket atama operatörü T0 "normal" atama operatörünü çağırır.

Neyi yanlış yapıyorum?

cevap

16

Bir Parametreler olarak rengin referansları alan fonksiyonlar hakkında kafa karıştırıcı şeyler, içsel olarak parametrelerini lvalues ​​olarak ele aldıklarıdır. Bu, parametreyi kullanmadan önce değiştirmenizi engellemektir, ancak alışması biraz zaman alır. Parametreyi gerçekten hareket ettirmek için, std :: move (veya std :: forward) öğesini çağırmalısınız. Yani size taşıma kurucusu tanımlamak için ihtiyaç olarak:

T(T&& o): T0(std::move(o)) { puts("move"); } 

ve gibi hareket atama operatörü:

T& operator=(T&& o) { puts("move assign"); return static_cast<T&>(T0::operator=(std::move(o))); } 
5

Sen sadece hiç SolDeğerler ile temel sınıfın eşyalarını aradığınız: is

void foo(int&){} // A 
void foo(int&&){} // B 

void example(int&& x) 
{ 
    // while the caller had to use an rvalue expression to pass a value for x, 
    // since x now has a name in here it's an lvalue: 
    foo(x); // calls variant A 
} 

example(std::move(myinteger)); // rvalue for us, lvalue for example 

şunlar gereklidir:

T(T&& o): 
T0(std::move(o)) // rvalue derived converts to rvalue base 
{ 
    puts("move"); 
} 

Ve: fazlasının

T& operator=(T&& o) 
{ 
    puts("move assign"); 

    T0::operator=(std::move(o))); 

    return *this; 
} 
İlgili konular