【问题标题】:An alternative to a static variable in a member function成员函数中静态变量的替代方法
【发布时间】:2011-09-10 02:44:45
【问题描述】:

我一直误以为成员函数中定义的静态变量仅限于特定的类实例。

为了说明我的误解:

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

【问题讨论】:

  • 完全不清楚您要完成什么。如果您删除 static 或在静态变量声明后立即执行分配(如 Mahesh 所建议),它们都会为您提供预期的输出。
  • @Victor 在代码示例中,我滥用静态在编译时生成匿名成员变量。对GetArray 的后续调用将返回对匿名成员变量的引用。

标签: c++ templates static


【解决方案1】:

如果我理解您的困惑,另一种选择是成员变量...

template<typename T>
struct Simple {
    T storage;

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

【讨论】:

  • 不幸的是,我使用静态变量来存储类的数据,所以我可以查找类型 int 并检索我存储在那里的任何内容。
  • 这更多是您系统的设计限制。为此,您需要将数据放入无类型字段并存储某种标识符,然后使用它来取回数据。结束拙见。
【解决方案2】:
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;
}

这应该得到你想要的。

【讨论】:

  • 但是存储仍然是静态的,所以下一个执行它的类实例仍然会覆盖该值,对吧?
  • 是的,你是对的。如果每个实例都需要它自己的变量,那么 OP 根本没有必要将其声明为静态。
【解决方案3】:

你可以把它变成一个普通的、非静态的类变量,尽管这需要类是一个模板而不是函数......

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

【讨论】:

    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2023-03-06
    相关资源
    最近更新 更多