【问题标题】:Singleton instanced two times单例实例两次
【发布时间】:2014-12-11 14:20:35
【问题描述】:

我正在重写这个问题,因为我意识到我在第一次问这个问题时并没有理解这个问题,问题变得非常混乱。

我在库中有一个单例模式类 (Meyers Singleton)。当我在我的主应用程序和该库中的 .cpp 中调用 getInstance() 时,我得到两个不同的地址。当我在 Librarys 标头中调用 getInstance() 时,它的地址相同。

main.cpp

 #include <GameEngine.h>
 #include <iostream>

 main() {

     GameEngine& engine = GameEngine::getInstance();
     std::cout << &engine;    // gives me address A

     engine.doSomething();

}

现在在 Headerfile 中调用 getInstance 时可以正常工作了:

内部库 GameEngine.h

class GameEngine {

public:
    static jglEngine& getInstance() // Singleton is accessed via getInstance()
    {
        static jglEngine instance; // lazy singleton, instantiated on first use
        return instance;
    }
    
    void doSomething() {
        GameEngine& engine = GameEngine::getInstance();
        std::cout << &engine;    // gives me also address A

    }
private:
   GameEngine() {};

   GameEngine(GameEngine const&); // prevent copies
   void operator=(GameEngine const&); // prevent assignments
}

但是当我没有将函数定义放在头文件中,而是在源文件中时,它给了我一个不同的地址:

内部库 GameEngine.cpp

 #include "GameEngine.h"
 
 void GameEngine::doSomething() {
      
      GameEngine& engine = GameEngine::getInstance();
      std::cout << &engine;    // gives me address B

 }

找到了解决方案:D

我把动态库改成静态库,就可以正常工作了。

【问题讨论】:

  • 但是我在这里没有使用不同的线程,或者是吗?
  • Can't reproduce。请发布一个完整的(但最少的)测试用例来重现问题。
  • 对不起,我自己测试了一下,发现我在这里发帖时犯了一个错误。现在应该是正确的。
  • mmh,当我像您一样在一个文件中执行此操作时,它也适用于我。那么在可可框架中使用引擎可能是个问题?
  • 现在改写问题,真正解决问题,对不起!

标签: c++ cocoa singleton


【解决方案1】:

每个 DLL 都有自己的静态数据实例,这实际上是使用 DLL 的真正问题之一(但也可能是使用 DLL 的优点之一)

有一些技巧可以克服这个问题,例如使用线程区域设置存储,但通常你必须确保 DLL 被传递给单例,可能在主应用程序中创建单例,然后将其作为某种上下文对象传递。

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2013-06-08
    相关资源
    最近更新 更多