2014-05-18 48 views
0

如何自定義一個C++列表容器,以便它可以保存不同類型的結構?如何定製一個C++列表容器,以便它可以容納不同類型的結構體?

例如

struct A 
{ 
    int a; 
    int b; 
} 

struct B 
{ 
    float a; 
    float b; 
} 


#include <list> 
using namespace std; 
int main() 
{ 
    ... 
    ... 
    A a; 
    a.a = 1; 
    a.b = 2; 

    B b; 
    b.a = 123.444; 
    b.b = 11.222; 

    List.push_back(a); 
    List.push_back(b); 

    return 0; 
} 
+1

何必呢?用一些常規方法制作父類,從中提取數據,並從中繼承2個類,每個類都有自己的私有數據。並使用父類作爲列表的類型。 – user3152069

+1

要麼存儲指向基類的指針,要麼使用元組,要麼重新考慮設計。 – user2672165

+3

@prgbenz你通常不會把東西放在一個不能被相同訪問的容器中。使用具有虛函數的公共基類等。如果從'list'中彈出一個項目,編譯器如何在運行時知道結構是「A」還是「B」? – Jeff

回答

0

我建議boost:: any。但是,真的,多態不能解決你的問題嗎?

+3

爲什麼不使用_boost :: variant_而不是_boost :: any_? – nosid

1

爲什麼不是polymorphism和指向對象的指針列表? 請注意物體的使用壽命。一旦兩個對象超出範圍,列表中的指針就會失效。你可以選擇dynamically allocate)這兩個元素和刪除他們當你完成後,然後從列表中刪除他們。

後來編輯:我覺得你是新來的C++。在研究動態分配之後,我建議你查看智能指針。他們通過做自己解除手動管理內存的負擔:

unique_ptrshared_ptr

您可以使用它們的列表,而不是赤裸裸的指針內。

struct Base 
{ 
    virtual ~Base(){} 
}; 
struct A : public Base 
{ 
    int a; 
    int b; 
}; 

struct B : public Base 
{ 
    float a; 
    float b; 
}; 


#include <list> 
using namespace std; 
int main() 
{ 
    ... 
    ... 
    A a; 
    a.a = 1; 
    a.b = 2; 

    B b; 
    b.a = 123.444; 
    b.b = 11.222; 

    std::list<Base*> l; 
    l.push_back(&a); 
    l.push_back(&b); 

    return 0; 
} 
+0

如果對象超出範圍,則可能會出現懸掛指針,但除此之外,存在輕微的危險+1。可以使用智能指針使代碼更安全,並使用new/delete。 – vsoftco

+0

@vsoftco我儘量保持答案儘可能簡單,我認爲OP是C++的新手。 –

1

在某些情況下,將不同類型存儲在容器中是有意義的。 C++通過聯盟支持這些用例,但此功能非常基礎。如果您確實需要在容器中存儲不同類型,我推薦使用boost :: variant而不是聯合。我也推薦使用std::vector而不是std::list,因爲否則使用這種優化沒什麼意義。

這裏是提升一個例子::變種

std::vector<boost::variant<A, B>> items; 
A a = ...; 
B b = ...; 
items.push_back(a); 
items.push_back(b); 
struct get_length : boost::static_visitor<double> 
{ 
    double operator()(const A& f) const { return calc(f.a, f.b); } 
    double operator()(const B& b) const { return calc(b.a, b.b); } 
    double calc(double a, double b) const { return std::sqrt(a * a + b * b); } 
}; 
for (auto&& item : items) { 
    double d = boost::apply_visitor(get_length(), item); 
    std::cout << d << '\n'; 
} 
相關問題