2012-08-09 22 views
5

Başlık hemen hemen her şeyi söylüyor. Temelde, yasal bu yapmaktır: gördüğüm diğer yazılarda dayanarakC++: <Base> vektörü Türetilmiş nesneler içerebilir mi?

class Base { 
    //stuff 
} 

class Derived: public Base { 
    //more stuff 
} 

vector<Base> foo; 
Derived bar; 
foo.push_back(bar); 

aşağıdaki tamamdır, ama buna parçacığı güvenli hale getirmek için zor çünkü bu durumda işaretçileri kullanmak istemiyoruz .

vector<Base*> foo; 
Derived* bar = new Derived; 
foo.push_back(bar); 
+0

Neden parçacığı olduğunu Base uygulama denir göreceksiniz herhangi bir şekilde güvenlik burada uygun? İstisna güvenliği demek istedin mi? Eğer öyleyse, evet, 'push_back' bir sallanma işaretçisini bırakarak bir istisna atabilir. Bunu işlemek için akıllı işaretçiler kullanabilirsiniz. – DanielKO

+0

@DanielKO Bir üretici ve tüketici iş parçacığı arasında bir arabellek olarak bir STL kapsayıcısı kullanıyorum. Kapsayıcıyı işaretçilerle doldurmak istemiyorum, çünkü kapsayıcının bir muteks ile korunmasına rağmen, herhangi bir iş parçacığı başka bir veriye işaret ettiğinde, bu veriler korunmuyor. – Beezum

+0

Bu, bir iplik güvenliği problemi değildir. İşaretçiler olmasa bile, bir parçayı güvenli olmayan bir şekilde parçalara ayırabilir. Yapmanız gereken tek şey, uygun semantikleri tanımlamaktır, böylece içerikler (işaretçiler veya doğrudan olarak depolanır) uygun tutarlılık tutarlılık mekanizmaları olmadan değiştirilmez. Özellikle, eğer sınıfın bir kullanıcısı “izin” olmaksızın öğeye bir işaretçi kaydedebiliyorsa, aynı şekilde bir işaretçi ya da referans almayacağını düşündüren şey nedir? – DanielKO

cevap

13

Hayır, Derived nesneleri sliced olacak: tüm ek üyeler atılacak.

İşlenmemiş işaretçiler yerine, std::vector<std::unique_ptr<Base> >'u kullanın.

+0

@LuchianGrigore " vektörü Türetilmiş nesneler içerebilir?" -> Hayır, dilimlenecekler, böylece sadece 'Base' nesneleri olacaklar. Yasadışı değil, ama bu da doğru değil. – mfontanini

+1

@LuchianGrigore "Hayır, vektör türetilmiş Nesneleri içeremez". Çünkü bir kere dilimlendiklerinde artık "Türetilmiş" değiller. – ecatmur

+1

@Heisenbug, vektörde biten "Base", itilmekte olan "Derived" nesnesinden oluşturulmuş bir kopyadır. Bir kopya inşaatı bir sızıntı oluşturursa, kodunuzda bir sorun var demektir: D. – mfontanini

4

O yasal ama nesne dilimleme muzdarip. Temel olarak, Base nesnesinin bir vektörü olacaktır. Polimorfizm yok, türetilmiş nesneler için tür bilgisi kaybolur ... Sadece vektöre Base nesnesi ekliyor olmanız gibi.

Bunun yerine akıllı işaretçiler kullanabilirsiniz.

0
vector<Base> foo; 
Derived bar; 
foo.push_back(bar); 

Bu Baz nesne itme eşittir, push_back böyle bildirildiği için:

void push_back (const T& x); 

Yani, derleyici örtülü arka plana itmesi dönüşüm yapacak ve vektör bellek havuza kopyalarım. Hayır, vector<Base> içinde Derived içermek mümkün değildir. Base olacaktır. Sonra Base için bazı sanal işlev eklemek vector<Base> itin ve ardından Vektörün yeni nesneden diyoruz, Derived nesne oluşturmak, Derived bunu geçersiz kılarsanız

, sen

İlgili konular