有没有办法为模板类(所有类型)没有破坏封装有一个静态变量 [英] Is there a way to have a single static variable for a template class (for all types) without breaking encapsulation

查看:133
本文介绍了有没有办法为模板类(所有类型)没有破坏封装有一个静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



template< class T&好吧,上面的代码将为每个类型生成一个名为foobar的Bar对象<$ c $ {
c> T
,但这不是我想要的,我基本上想要一种方法来声明一个类型Bar的变量,所以每个对象类型 Foo 可以访问相同的 foobar 变量,与 T 无关。



我试图使用另一个类来存储私有的东西,但是没有工作,因为标准不允许像 template< class T>朋友类Foo< T> ;;



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

  Bar Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar; 
template< class T> class Foo {static Bar& foob​​ar;};
template< class T>酒吧& Foo T; :: foobar = Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar;

当然,你可以另外使用一个细节命名空间(这是我目前正在做的)方式,真的禁止用户搞砸你的私人静态变量?



另外,当你必须以类似的方式声明很多静态方法时,这个解决方案会变得很杂乱,因为你很可能需要大量使用friend关键字, code> friend RetType Foo_detail :: StaticFunc(ArgT1,ArgT2)。



用户不会有一个漂亮的界面,使用那些像 Foo< T> :: someFunc()的函数,但是它们必须调用 Foo_static :: someFunc )(如果您使用命名空间 Foo_static 用于公共静态函数)。



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



编辑:
基于所有的anwsers,i尝试下面的,它的工作原理:

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

class FooBase
{
static Bar foobar;
public:
template< class T>朋友类Foo;
};
Bar FooBase :: foobar;

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

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

解决方案

可能继承静态成员?

  class OneBarForAll 
{
protected:
static Bar foobar;
};

template< class T>
class Foo:public OneBarForAll
{

};

许多 Foo< T> ,但只有一个 OneBarForAll



一个潜在的问题是没有什么能阻止其他用户代码从继承 OneBarForAll 并修改 foobar



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


I need a way to have a single static variable for all kinds of types of my template class

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

Well, the line above will generate a Bar object named foobar for every type T, but this is not what i want, i basically want a way to declare a variable of type Bar, so every object of type Foo has access to the same foobar variable, independent of T.

I tried to use another class to store the private stuff, but that doesnt work, because the standard does not allow stuff like template <class T> friend class Foo<T>;

So the obvious solution (shown below) is to have a global variable Bar foobar, but this obviously violates the information hiding concept (of proper encapsulation):

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 you can additionally use a detail namespace (thats what i am currently doing), but is there another way which really prohibits users from messing around with your private static variables ?

Additonally this solution will get quite messy when you have to declare lots of static methods in a similar fashion, because you will most likely have to extensivly use the friend keyword like friend RetType Foo_detail::StaticFunc(ArgT1, ArgT2).

And the users wont have a nice interface since they cant use those functions like they are used to Foo<T>::someFunc() but instead they will have to call something like Foo_static::someFunc() (if you use the namespace Foo_static for public static functions).

So is there any other solution which does not break encapsulation, and/or does not introduce lots of syntax overhead ?

EDIT: based on all your anwsers, i tried following, and it works as intended:

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;
};

this solution has the benefit, that users can not inherit from FooBase.

解决方案

Perhaps inherit the static member?

class OneBarForAll
{
protected:
  static Bar foobar;
};

template <class T>
class Foo : public OneBarForAll
{

};

Lots of Foo<T>'s will be made, but only one OneBarForAll.

One potential problem with this is that there's nothing stopping other users of the code from inheriting from OneBarForAll and modifying foobar anyway.

Ideally you do want the template friend, as that best describes the access requirements of your design, but C++ does not currently allow that.

这篇关于有没有办法为模板类(所有类型)没有破坏封装有一个静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆