2010-02-11 59 views
3

我需要一种方法来对所有种类型我的模板类的单个静态变量有没有办法有一个模板类(所有类型的)一个静态变量不破坏封装

template <class T> class Foo { static Bar foobar;};

好吧,上面这行会为每个类型T生成一个名为foobar的Bar对象,但这不是我想要的,我基本上想要一种方法来声明Bar类型的变量,因此Foo类型的每个对象都可以访问相同的foobar变量,独立于T

我试图用另一个类来存储私人的东西,但是,这并不工作,因为标准不容许这样的东西template <class T> friend class Foo<T>;

那么显而易见的解决方案(如下图所示)是有一个全局变量Bar foobar,但是这显然违反了(正确封装)的信息隐藏的概念:

Bar Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar; 
template <class T> class Foo { static Bar& foobar;}; 
template <class T> Bar& Foo<T>::foobar=Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar; 

Ofcourse,你还可以使用一个详细的命名空间(这就是我目前在做什么),但有其真正禁止用户乱搞的另一种方式与你的私人静态变量?

此外,当您必须以类似的方式声明大量静态方法时,此解决方案会变得非常混乱,因为您很可能必须全面使用像friend RetType Foo_detail::StaticFunc(ArgT1, ArgT2)这样的friend关键字。

而且用户不会有一个漂亮的界面,因为他们不能使用像它们被用来Foo<T>::someFunc()这些功能,而是他们将不得不调用像Foo_static::someFunc()(如果你使用的命名空间Foo_static公共静态函数)。

那么有没有其他的解决方案不打破封装,和/或不会引入大量的语法开销?

编辑: 根据您的所有anwsers,我尝试以下,和它的作品像预期一样:

typedef int Bar; 
template <class T> class Foo; 

class FooBase 
{ 
    static Bar foobar; 
    public: 
     template <class T> friend class Foo; 
}; 
Bar FooBase::foobar; 

template <class T> class Foo : public FooBase 
{ 
    public: 
    using FooBase::foobar; 
}; 

该解决方案具有的好处,用户无法从FooBase继承。

+0

你可以声明一个不相关的类是一个朋友,而不是这个语法。通过@rmn – 2010-02-11 18:01:37

回答

9

也许是继承了静态成员?

class OneBarForAll 
{ 
protected: 
    static Bar foobar; 
}; 

template <class T> 
class Foo : public OneBarForAll 
{ 

}; 

很多Foo<T>的意志进行,但只有一个OneBarForAll

这个问题的一个潜在问题是没有任何东西阻止代码的其他用户继承OneBarForAll和修改foobar

理想情况下,您确实需要模板好友,因为它最能描述您的设计的访问需求,但C++目前不允许。

+0

+1查看答案。这正是我所建议的。 – rlbond 2010-02-11 17:49:00

3

你可以这样做:

struct Base { 
    static Foo foo; 
}; 
//init foo here 

template<typename T> 
struct Derived : Base { 
... 
}; 
... 
Derived<Bar>::foo; 

它工作在G ++

1

为什么不从非模板基类继承?

4

template <class T> friend class Foo<T>; 

语法

template <class T> friend class Foo; 

(这意味着富的每一个实例是类定义它的朋友)

因此,也许你可以去与你之前排除的解决方案。

+0

我在我的解决方案中也使用了这个,看到我的问题 – smerlin 2010-02-11 18:06:44