2011-09-10 20 views
2

我一直依赖于成员函数中定义的静态变量仅限于特定类实例的误解。成员函数中静态变量的替代

为了说明我的误解:

#include <iostream> 
#include <string> 

struct Simple { 
    template<typename T> 
    T & Test(const T & Value) { 
     static T Storage = Value; 
     return Storage; 
    } 
}; 

int main() { 
    Simple A; 
    Simple B; 

    std::string Foo = A.Test(std::string("Foo")); 
    std::string Bar = B.Test(std::string("Bar")); 

    std::cout << Foo << ' ' << Bar << std::endl; 
} 

我所期望的行为将导致

美孚的输出杠

是否有可能导致一个简单的替代我预期的行为?

编辑

一个缩减版本,之类的有问题:

class SignalManager { 
    private: 
     template<typename T> struct FunctionPointer { typedef boost::function1<void, const T &> type; }; 
     template<typename T> struct Array { typedef std::vector<typename FunctionPointer<T>::type> type; }; 

     template<typename T> 
     typename Array<T>::type & GetArray() { 
      static typename Array<T>::type Array; 
      return Array; 
     } 

    public: 
     template<typename T, typename M> 
     void Broadcast(const M & Value) { 
      typename Array<T>::type::iterator Iterator; 
      for(Iterator = GetArray<T>().begin(); Iterator != GetArray<T>().end(); ++Iterator) { 
       (*Iterator)(Value); 
      } 
     } 

     template<typename T, typename F> 
     void Connect(const F & Function) { 
      GetArray<T>().push_back(Function); 
     } 
}; 
+0

它是完全不清楚什么这是你正在努力完成的。如果您在静态变量声明(如Mahesh所建议的)之后删除静态变量或执行指定的权限,它们都会给您预期的输出。 – greatwolf

+0

@Victor在代码示例中,我滥用static来在编译时生成匿名成员变量。随后对'GetArray'的调用将返回一个对匿名成员变量的引用。 – Timesquare

回答

2

如果我理解你的困惑,是替代成员变量...

template<typename T> 
struct Simple { 
    T storage; 

    T & Test(const T & Value) { 
     storage = Value; 
     return Storage; 
    } 
}; 
+0

不幸的是,我正在使用静态变量来存储这个类的数据,所以我可以查找'int'类型并检索我在那里存储的任何东西。 – Timesquare

+0

这更多的是您的系统的设计限制。为此,您需要将数据放入一个无类型的字段中,并存储某种标识符并使​​用它来获取数据。结束谦虚的意见。 –

0
static T Storage = Value; 

尽管多次执行,上述语句只执行一次请拨打会员功能Test。因此,分开声明和初始化。

template<typename T> 
T & Test(const T & Value) {   
    static T Storage; 
    Storage = Value; // Now, this is guaranteed to execute during member function calls. 
    return Storage; 
} 

这应该得到你想要的。

+0

但是存储仍然是静态的,所以执行它的下一个类实例仍然会覆盖该值,对吧? –

+0

是的,你是对的。如果每个实例都需要它自己的变量,那么OP根本没有必要声明它是静态的。 – Mahesh

0

你可能只是使之成为一个常规,非静态类变量,尽管这将需要类是模板,而不是功能...

template<typename T> 
struct Simple 
{ 
    T& Test(const T& value) 
    { 
     storage = value; 
     return storage; 
    } 
private: 
    T storage; 
}