2013-08-16 26 views
16

yapılarak oluşturulmasının doğru bir yolunun aktarılması yolu std::vector<unique_ptr<int> >'un sahipliğini oluşturulmakta olan bir sınıfa aktarmanın uygun yolu nedir?Bir std :: vektör <std :: unique_ptr < int>> mülkünün

Aşağıda, yapmak istediklerimin kod gösterimi verilmiştir. Doğru olmadığını (derlemeyeceğimi) ve “teklik” ini, vektörü yapıcıya değer veya referans olarak iletip geçirmediğimi fark ettim. Foo'nun vektörün yeni sahibi olmasını istiyorum ve çağrı işlevinin sahipliğinden vazgeçmesini istiyorum. Bunu yapmak için std::unique_ptr<std::vector<std::unique_ptr<int> > > almak için kurucuya ihtiyacım var mı?

Foo.h

class Foo 
{ 
public: 
    Foo(vector<std::unique_ptr<int> > vecOfIntPtrsOwnedByCaller); 

private: 
    vector<std::unique_ptr<int> > _vecOfIntPtrsOwnedByFoo; 
} 

foo.cpp

Foo::Foo(std::vector<std::unique_ptr< int> > vecOfIntPtrsOwnedByCaller) 
{ 
    _vecOfIntPtrsOwnedByFoo = vecOfIntPtrsOwnedByCaller; 
} 

Herhangi bir yardım çok takdir - Bunu doğru yol arıyoruz net dolaştılar ettik. Teşekkürler!

+1

'std :: vector >' ya gerektirir geçici olarak veya arayan kişi, std :: move işlevini kendi vektörlerinde kullanamaz, çünkü sadece kopyalanamaz. Gerçekten açık yapmak istiyorsanız, std :: vector <...> && ''yi düşünün. Bundan sonra, üyenize (üye-başlatıcılarda!) “Std :: move” ile ilerleyin. – Xeo

+1

Vektörün benzersiz olarak sahip olunmasını mı yoksa burada bulunan öğeleri mi istiyorsunuz? –

+0

Yörüngedeki Hafiflik Yarışları - Her ikisi. – Jen

cevap

16

std::unique_ptr<T>, kopyalanamaz ancak taşınabilir bir türüdür. Yalnızca bir "std:vector<T>" türünde taşıma tipine sahip olmak, std::vector<T>'u yalnızca taşıma işlemini gerçekleştirir. Derleyicinin nesneleri otomatik olarak hareket ettirebilmesi için, taşınma veya taşınma için bir r değerine sahip olmanız gerekir. Yapıcınız içinde, vecOfIntPtrsOwnedByCaller nesnesinin bir l değeri olduğunu, ancak birincisine rağmen, int s işaretine sahip olmasına rağmen, arayan kişi nesneyi oluşturduğunda arayandan "çalındı". Bir l-değerden taşımak için, std::move() (veya eşdeğer bir şey) kullanmak gerekir: daha sonra ilk varsayılan inşa elemanı ve önlemek tercih

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller) 
{ 
    _vecOfIntPtrsOwnedByFoo = std::move(vecOfIntPtrsOwnedByCaller); 
} 

ya,

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller) 
    : _vecOfIntPtrsOwnedByFoo(std::move(vecOfIntPtrsOwnedByCaller)) 
{ 
} 

ikinci yaklaşım hareketlerinin ona atama ve bunun yerine üyeyi doğrudan taşınır. Ben de argümanı bir r-değeri referansı yapardım ama bu gerekli değil. Yalnızca bir r-değeriyle bağlanan edilebilir bir şey, örneğin, türe Foo nesneleri kurulabileceğini

Not:

int main() { 
    Foo f0(std::vector<std::unique_ptr<int>>()); // OK 
    std::vector<std::unique_ptr<int>> v; 
    Foo f1(v); v// ERROR: using with an l-value 
    Foo f2{v}; v// ERROR: using with an l-value 
    Foo f3 = v; // ERROR: using with an l-value 
    Foo f4(std::move(v)); // OK: pretend that v is an r-value 
} 
+0

Referans ve takas ile çözüm geçerli mi? Yani bu Foo (vektör > & v) {this-> v.swap (v); } '. Açıkçası cevabınızın doğru ve daha iyi olduğunu biliyorum - ancak "swap" ın kullanılması OP'nin "sahipliğin aktarılması" talebinin bir yolu olabilir mi? – PiotrNycz

+0

@PiotrNycz: 'std :: vektör <...>' 's swap()' da çalışırdı, ancak üye başlatıcı listesindeki 'std :: move()' ifadesini kullanmak, içeriği aktarmanın deyimsel yoludur. –

+0

Teşekkürler Dietmar, bir rengin referansı alarak bir kurucunun bir örneğini ve buna bir vektörün nasıl geçeceğini gösterebilir misiniz? Hangi sürümü kullanacağınıza nasıl karar veriyorsunuz? – Jen

İlgili konular