有没有办法在不破坏封装的情况下为模板类(适用于所有类型)提供单个静态变量

时间:2010-02-11 17:27:42

标签: c++ templates static

我需要一种方法来为我的模板类的各种类型提供单个静态变量

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;

当然,你可以另外使用一个详细命名空间(这就是我目前正在做的事情),但还有另一种方法可以真正禁止用户搞乱你的私有静态变量吗?

另外,当你必须以类似的方式声明许多静态方法时,这个解决方案会变得非常混乱,因为你很可能必须使用像friend RetType Foo_detail::StaticFunc(ArgT1, ArgT2)这样的朋友关键字。

并且用户不会有一个很好的界面,因为他们不能像Foo<T>::someFunc()那样使用这些函数,而是他们必须调用类似Foo_static::someFunc()的东西(如果你使用命名空间{{1}对于公共静态函数)。

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

编辑: 基于你所有的anwsers,我试着跟随它,它按预期工作:

Foo_static

此解决方案的好处是,用户无法从FooBase继承。

4 个答案:

答案 0 :(得分:9)

也许继承静态成员?

class OneBarForAll
{
protected:
  static Bar foobar;
};

template <class T>
class Foo : public OneBarForAll
{

};

将会制作很多Foo<T>,但只有一个OneBarForAll

这方面的一个潜在问题是,无论如何都没有阻止其他代码用户继承OneBarForAll并修改foobar

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

答案 1 :(得分:4)

的语法
template <class T> friend class Foo<T>;

template <class T> friend class Foo;

(这意味着Foo的每个实例都是你定义它的类的朋友)

所以也许你可以选择你之前排除的解决方案。

答案 2 :(得分:3)

你可以这样做:

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

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

它适用于g ++

答案 3 :(得分:1)

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