2012-02-02 101 views
2

我想創建一個模板類,其中包含一個只有一個的靜態對象列表。我到目前爲止的工作,但它給了我的每個不同類型的B類參數「mylist」的副本。我怎樣才能改變它,讓我得到一個「mylist」類B的所有實例化,而不管模板參數如何?在模板中使用靜態變量

這是我所:提前:)

template <class T> class A { 
    ... 
}; 
template <class T> class B { 
    static list<A<T> > mylist; 
    ... 
}; 
template <class T> list< A<T> > B<T>::mylist; 

感謝

+7

你基本上誤解了模板。給定'template class Foo;',不同'T'的'Foo '的每個實例都是完全不同的類型。因此,如果'Foo <>'包含一個靜態數據成員,則針對不同'T'的每個'Foo '實例將包含不同的靜態數據成員。要有一個可以包含不同類型的數據成員,請查看[Boost.Variant](http://www.boost.org/libs/variant/),如果事先已知所有類型,或者[Boost.Any](http: //www.boost.org/libs/any/)。 (但是,真的,你的設計聽起來非常可疑。) – ildjarn 2012-02-02 21:48:54

+0

你是在單身之後嗎? http://www.infernodevelopment.com/singleton-c – Joel 2012-02-02 21:53:43

回答

4

如何改變它,這樣我只有一個副本

可以從繼承通用(非模板化)基類,以確保每個模板實例化都沒有實例。

...包含任何類型?

這取決於您的期望。我將從你的例子中假設「任何類型」意味着「模板類A的任何實例化」。

由於這些類型的大小可能會有所不同,因此您最好持握指向對象的指針。

這是一個例子解決方案,可以解決這兩個問題。

class ACommon { 
    // Put a common virtual interface here. 
}; 

template <class T> class A : public ACommon { 
}; 

class BCommon { 
    // You'll have a single, common static here. 

    static list<shared_ptr<ACommon> > mylist; 
}; 

template <class T> class B : public BCommon{ 

}; 
1

你不能「只」在列表中有任何類型,並排居住。根據您對該列表以及其中的對象所做的操作,有幾件事情要做。

德魯解決方案的另一種選擇是: 如果您想爲所有實例化使用單個列表,則您肯定需要BCommon。如果您不想在接口後面隱藏A類型,則可以使用Boost :: any或Boost :: variant來保存A對象。

+0

是的,'boost :: any'和'boost :: variant'在這裏是很好的用例。尼斯。 – 2012-02-02 22:13:33

+0

'boost :: variant'對新手來說有點危險,由於它是一個聯盟,因此它假定最大類型的大小。一個新手,沒有注意到,可能會浪費大量的內存,只是爲了在一百萬個「未來」中存儲一個大對象。 'boost :: any'是一個不同的故事。雖然它不會因爲錯誤的轉換(如void *)而導致未定義的行爲,但由於未處理的'bad_cast_exception',它可能會使您的程序「在現場」崩潰。恕我直言,對於90%的案例,您的解決方案是要走的路。 – enobayram 2012-02-02 22:27:01