2014-10-06 25 views
7

C++ uygulamasında 3 farklı veri türünü saklayabilen bir vektör yapmaya çalışıyorum. Destek kütüphanesini kullanmak istemiyorum. şey gibi:3 farklı veri türüne sahip olabilen vektör C++

vector<type1, type2, type3> vectorName; 

Ben bir şablon yapmak gerekir mi? Ve eğer evet, bunu nasıl yapardım?

+0

Farklı türlerdeki başvuruları saklamak için bir çeşit sarmalayıcı sınıfına/kapsayıcısına gereksiniminiz olabilir. Benzer bir soru [burada] (http://stackoverflow.com/questions/13461869/c-push-multiple-types-onto-vector) – Abbath

+0

Bkz. ['Tuple'] (http://www.cplusplus.com/reference/tuple /), belki. Vektörler (aka listeleri) bir veya daha fazla * homojen * öğe dizisidir. Tupllar, olası heterojen üyelerin sonlu (ve sabit büyüklükte) koleksiyonlarıdır. – user2864740

+2

Öğeleri her birinin 3 türünü içeren bir vektörün olmasını ister misiniz? Ya da tek tip veya diğerleri içerebilir bir vektör? – Galik

cevap

6

Aynı vektörde birden çok türün saklanmasının en kolay yolu, bir alt sınıfın alt türlerini yapmaktır; bunlar, daha önceden sınıflar değilse, istediğiniz türlerde sınıfları sarar.

class Parent 
{ 
    //anything common to the types should be declared here, for instance: 
    void print() //make this virtual if you want subclasses to override it 
    { 
    std::cout << "Printing!"; 
    } 

    virtual ~Parent(); //virtual destructor to ensure our subclasses are correctly deallocated 
}; 

class Type1 : public Parent 
{ 
    void type1method(); 
}; 

class Type2 : public Parent 
{ 
    void type2Method(); 
}; 


class Type3 : public Parent 
{ 
    void type3Method(); 
}; 
Daha sonra çocuk türlerine işaretçileri saklayabilir Parent işaretçiler vektör oluşturabilir

: vektör doğrudan erişim için kullanılan

std::vector<Parent*> vec; 

vec.push_back(new Type1); 
vec.push_back(new Type2); 
vec.push_back(new Type3); 

, sadece üyelere kullanmak mümkün olacak Parent'a aittir.

vec[0]->print(); 

Ama: Örneğin, yazabilir eleman tipi Parent* olarak ilan edilmiştir gibi

vec[0]->type1Method(); 

ve Parent türünün type1Method sahiptir. Eğer alt tip spesifik üyeleri erişmek gerekirse

, bunu böyle işaretçileri alt tip için Parent işaretçiler dönüştürebilirsiniz:

Parent *p = vec[0]; 

Type1 *t1 = nullptr; 
Type2 *t2 = nullptr; 
Type3 *t3 = nullptr; 

if (t1 = dynamic_cast<Type1*>(p)) 
{ 
    t1->type1Method(); 
} 
else if (t2 = dynamic_cast<Type2*>(p)) 
{ 
    t2->type2Method(); 
} 
else if (t3 = dynamic_cast<Type3*>(p)) 
{ 
    t3->type3Method(); 
} 

genellikle açık tip dallanma böyle bir durumu önlemek için daha iyi bir fikir olarak kabul rağmen ve bunun yerine sanal yöntemlere güvenir.

Yukarıdaki örnekte yaptığım gibi, dinamik ayırma kullanıyorsanız, vektörlerden çıkarmadan önce işaretçileri sildiğinizden emin olun. Alternatif olarak, (muhtemelen std::unique_ptr akıllı işaretçileri kullanmak ve bellek kendisi ilgilenelim: 3 farklı veri türlerini saklayabilirsiniz C bir vektör ++ yapmaya çalışıyorum

std::vector<std::unique_ptr<Parent>> vec; 
+0

Hiçbir şey silmediniz. Neden unique_ptr'nin bir vektörünü kullanmıyorsunuz, böylece otomatik olarak siliniyor? Ebeveynin sanal bir yıkıcıya ihtiyacı var. –

+0

@NeilKirk Doğru, sanal yıkıcıyı unutmuşum. Ben de akıllı işaretçilerden bahsedeceğim. – ApproachingDarknessFish

+0

Tamam Ben, vektörlerime farklı türler ekleyebilirim ama türlerdeki belirli yöntemlere erişemiyorum. Bu farklı yöntemlere nasıl erişebilirim? Örneğin, vec [i] .print(); Yardımın için teşekkürler! –

5

.

cevap burada gerçekten özellikle kullanım durumuna bağlıdır

: nesneleri bir şekilde bağlı ve bir şekilde benzer ise

  1. - bir temel sınıf oluşturmak ve ondan tüm sınıfları türetmek, sonra yapmak bir union kullanmak - unique_ptr s üst sınıfa vektör mağaza nesneleri (böylece dahili) temel türleri ise

  2. , (detaylar için ApproachingDarknessFish cevabını bakınız) gruplar olduğu, türleri ve nesneler bilinmeyen tür ise

  3. , bir vector<yourUnionType> tanımlamak, ancak onlar, bir benzer bir arayüz paylaşan bir temel sınıf oluşturmak emin ve ondan (template <typename T> class container: public parent{};) templated çocuk sınıf türetmek ve birinci durumda böyle bir vector<unique_ptr<parent>>,

  4. oluşturmak nesneleri (örneğin vector depolar int, std::string ve yourType böylece), gibi bir union yoluyla bağlamak nedense bağlanamaz türlerinden ise . Veya - hatta daha iyi ...

... Zamanınız ve bir şeyler öğrenmek istiyorsanız - nasıl uygulandığını boost::any bakmak ve gerçekten kütüphane kendisi kullanmak istemiyorsanız, kendiniz uygulamayı deneyin . Göründüğü kadar zor değil.

+0

Seçenek 2'deki kısıtlama neden? – MSalters

+0

@MSalters çünkü güçlü bir inanıyorum ki eğer bir temel sınıf türetmek daha fazla nesne yönelimli bir çözümdür. Ayrıca - bir 'vektör' içindeki sendikaları kullanmak özellikle uygun değildir - ayrıca her bir sendikada depolanan türü içerecek ikincil bir vektörü saklamanız gerekir, böylece ona düzgün bir şekilde erişirsiniz ve önemsiz olmazlar. –

+0

Temel tipler için bir ayrımcıların vektörüne ihtiyaç duyulmaktadır, bu yüzden bir ayrım yapmak için bir sebep yoktur. Ve not ettiğiniz gibi, ortak bir taban sınıfının olmaması gerçek bir sorundur, bu yüzden neden 4'teki çirkin hack yerine 2. seçenekle uğraşmayın? – MSalters

İlgili konular