2012-08-03 14 views
7

Sınıfım için hareket semantiklerinin uygulanmasına biraz zaman harcıyorum ama şimdi onu kullanan işlevlerle uğraşıyorum.Anlambilim ve const başvuruları taşıyın

Tamam, öyleyse yığın için çok fazla veriye sahip olan bu nesneye sahibim: CLargeOb için hareket semantiği uygulamam (constructor and operator =). o nesneler çöpe atılan/taşınmasını sağlamak için her zaman mümkün değildir Ancak

void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

, bu yüzden bu iki işlevi eklendi: Bu ideal böyle kullanılır o zaten can, çalışmasına rağmen

void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = largeOb1; 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; 
    m_largeOb2 = largeOb2; 
} 

Bu nesnelerin 3 ya da daha fazlasını parametre olarak alan bir fonksiyona sahip olduğumda * ss'de büyük bir acıya dönüşeceğini tahmin ediyorum. Bunu şablonlar ya da 'mükemmel yönlendirme' kullanarak çözmenin akıllıca bir yolu yok mu?

+0

@MooingDuck: VS2010'da sorunsuz çalışıyor, sorun değil. = (&&) operatörünü çağırmak için, bunu std :: move veya && cast kullanarak açıkça çağırmalısınız. Ancak çözüm, aşağıda daha iyi sağlandı. – demorge

+0

@demorge: oh doğru, ismini değiştirdiğinde kuralların tamamen değiştiğini unutmuşum. –

+1

için özür dilerim Lütfen '(CLargeOb &&) largeOb1' yerine' std :: move (largeOb1) 'yazınız. Gelecek programcı nesilleri, non-idiomatic ve borderline okunamayan C/C++ mix yerine bir harekete izin veren standart C++ 11 yöntemini kullandığınız için size teşekkür edecektir. – fredoverflow

cevap

15

C++ 03'te olduğu gibi, kılavuz: Bir kopyasını istiyorsanız, parametre listesinden yapın.

Bu nesneyi almak nasıl arayan anlaşma sağlayan, sadece bakılmaksızın bir nesne olsun:

void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = std::move(largeOb1); // save as members and trash the originals 
    m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast) 
} 

Arayan:

OtherOb o; 

CLargeOb x, y; 
const CLargeOb z; 

o.Func(x, std::move(y)); // need x for later, done with y so move it 
o.Func(std::move(x), z); // done with x, necessarily copy z 

Bu birkaç uzman aşırı kadar etkilidir. Niye ya? Çünkü bunlar zaten sınıfta yapıcıları olarak var. Derleyici, sizin için çağrı sitesinde hangi çağrıyı yapacağınızı belirlesin, zaten ne yapacağını bilir.

+2

Onu seviyorum, çok basit! – demorge

+0

Bu, bir kez yerine iki kez mi hareket etmiyor? (NB: Tabii ki, bir ek hareket neredeyse farkedilmemelidir, bu yüzden zaten bıktım) – Sjoerd

+0

@Sjoerd: Evet, umut, derleyicinin bir yere taşınacağını; ve söylediğin gibi olmasa bile farketmez. – GManNickG