2012-02-02 93 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