在C ++中创建多个全局静态实例?

时间:2009-05-29 23:44:35

标签: c++ static singleton global

我们用于产品的其中一个库使用单例来访问它。我很确定它是作为静态实例实现的(它不是开源的)。这适用于单个文档应用程序,但我们的应用程序可能加载了多个文档。我假设访问该实例的内容是这样的:

Instance* getInstance() {
    static Instance* inst = new Instance();
    return inst;
}

在这种情况下,是否有某种方法可以有力地创造更多 一个例子?我唯一能想到的就是不仅要处理并使用某种类型的IPC来将它们联系在一起。我想不出任何不那么黑的东西。

我已经要求供应商实现某种类型的会话令牌,因此我可以拥有多个并发实例,但它们很大而且我们很小。

科里

修改:

  • 该机器是Windows机器
  • 全球静电基本上是一个大工厂。我想要某种类型的会话令牌,所以我可以很容易地说“从这个会话中释放所有资源”(没有办法重新初始化我所知道的全局静态)

我不会尝试一些狡猾的恶作剧来获得我想要的东西,而是用我自己的类包装整个东西并为每个getter添加一个会话密钥。在内部,我将跟踪已分配的内容添加我自己的发布方法以返回资源。由于很多原因,这是次优的,但我想不出更好的主意。

感谢大家的反馈。

5 个答案:

答案 0 :(得分:5)

即使你能够解决这个特定问题,同时让事情发生在进程中,我也会担心这个单身人士问题只是冰山一角。该库显然不是为您的场景设计的。

将DLL的每个负载隔离到它自己的进程听起来对我来说是正确的,而且对我来说并不苛刻,但当然它对你来说可能很昂贵。

答案 1 :(得分:4)

不幸的是,我无法看到你的推理存在缺陷。供应商做出了决定,您受其约束。他决定每个进程有一个实例,所以如果你想要多个实例,你必须拥有多个进程才能满足所有需要。

当然,如果你认为他的限制决定是任意的,并且没有充分的理由,你可以试图破解它。开始这条路的方法是在调试器中进行一些反汇编/汇编步进。如果您可以确认他的实例工厂完全按照您上面的结论工作,那么毫无疑问,您可以将一个允许创建多个实例的替代工具混合在一起。

但当然,这种方法的巨大风险在于,供应商代码库中依赖于他决定拥有单个实例的每一行代码都是一个时间炸弹,随时准备爆炸。该代码对您来说是不可见的。你是否准备下注零线?我知道克林特·伊斯特伍德会在这样的情况下说些什么; “你觉得朋友很幸运,你做得好吗?” : - )

答案 2 :(得分:2)

没有优雅的方法可以在一个程序空间中拥有单个对象的多个实例 - 但这是故意的。通常,在不希望有多个实例的情况下,您只使用单例。如果供应商使用单件实施其产品,则可能有充分的理由进行选择。

也许,如果您更详细地描述您的问题,可能还有其他方法可能。根据所提供的信息,很难说。单身对象有什么作用?为什么需要多个实例?

答案 3 :(得分:1)

除了你建议的进程间内容之外,我能想到的最好的黑客方法是将dll复制到一个新文件并手动加载新的dll并导入你为你创建的每个实例使用的所有函数。

希望这意味着静态变量不会在不同实例之间发生冲突,因为它们在技术上不在同一个dll中。但是这个解决方案有很多不好的地方,比如每个版本都克隆了dll中的所有代码,你将无法使用导入库,但必须加载dll并手动导入所有函数。

答案 4 :(得分:1)

我唯一可以想到的是,如果你足够幸运,可以将单例类定义为:

class Document {
public:
    static Document* getInstance() {
        static Document inst;
        return &inst;
    }
    virtual ~Document();
protected:
    Document();
private:
    struct Impl;
    Impl *pImpl;
};

如果你可以对它进行子类化,并且子类可以访问构造函数,那么你可以创建一个可实例子类,如:

class MyDocument: public Document {
public:
    MyDocument(): Document() {
    }
};

这可能不完全安全,因为实施者可能做出了一些令人讨厌的假设。但这是一个想法或某种方法可能有一些工作机会。运气好的话,如果你提到它,供应商可能会接受这个选项......祝你好运。