2009-05-29 39 views
4

我们用于我们产品的一个库使用单例来访问它。我很确定它是作为一个静态实例来实现的(它不是开源的)。这适用于单个文档应用程序,但我们的应用程序可能会加载多个文档。我假设访问实例写到这样的事:在C++中创建多个全局静态实例?

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

在这样的情况下,有一些方法能够稳健地创造超过 一个实例?我能想到的唯一的事情就是不仅仅是处理和使用某种类型的IPC来将它们连接在一起。我想不出有什么不好的。

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

科里斯

编辑:

  • 机器是Windows机器
  • 全局静态基本上是一个大工厂。我想要一些类型的会话令牌,所以我可以轻松地说:“从这次会议释放所有的资源”(有没有办法重新初始化全局静态,我知道的)

而不是尝试一些狡猾的诡计为了得到我想要的东西,我打算用我自己的类包装整个东西,并为每个吸气剂添加一个会话密钥。在内部,我将跟踪已分配的内容,添加我自己的发布方法以返回资源。由于许多原因,这是不理想的,但我想不出一个更好的主意。

感谢大家的好评。

+0

你在什么操作系统平台上? – Skrymsli 2009-05-29 23:47:46

+4

这就是为什么单身人士是邪恶的。除非它真的是严重的东西,只能有一个对象,它不应该是一个单身。让其他人决定该对象有多少个实例。 – 2009-05-30 01:05:53

回答

1

,我能想到的唯一的事情是它的子类,如果你足够幸运,有单例类等被定义:

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

如果你可以继承它,子类将有机会获得构造函数,那么你可以创建一个instanceable子类,如:

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

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

4

不幸的是,我看不出你的推理有缺陷。供应商已做出决定,并且您受其约束。他已经为每个进程决定了一个实例,所以如果你想要多个实例,你必须有多个进程以及所有需要的进程。

当然,如果你认为他的限制决定是任意的,并且没有充足的理由,你可以试着绕​​过它。在这条路上开始的方法是在调试器中进行一些反汇编/汇编步骤。如果您可以确认他的实例工厂的工作原理与上面的结论完全相同,那么您无疑可以共同创建一个允许创建多个实例的替代方案。

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

5

即使你能解决这个问题,同时让所有事情都发生在proc中,我会担心这个单例问题只是冰山一角。图书馆显然不是为你的场景设计的。

将DLL中的每个负载分离到它自己的进程中听起来都很正确,而且对我来说不是很好,尽管当然这对您来说可能会很贵。

2

在一个程序空间中没有优雅的方法可以使单个对象有多个实例 - 但这是有意的。一般情况下,只有在不希望有多个实例的情况下才使用单例。如果供应商使用单例实现他们的产品,则可能有充分的理由选择。或许,如果你更详细地描述你的问题,可能还有其他的方法可能。根据所提供的信息很难说。单身物体是做什么的?为什么你需要它的多个实例?

1

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

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