单例实例化了两次

Singleton instanced two times

本文关键字:两次 实例化 单例      更新时间:2023-10-16

我正在重写这个问题,因为我意识到我第一次问这个问题时并不明白这个问题,这个问题变得非常混乱。

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

主.cpp

 #include <GameEngine.h>
 #include <iostream>
 main() {
     GameEngine& engine = GameEngine::getInstance();
     std::cout << &engine;    // gives me address A
     engine.doSomething();
}

现在,在头文件中调用getInstance时,它可以正常工作:

内部图书馆游戏引擎.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
}

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

在图书馆游戏引擎中.cpp

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

找到解决方案:D

我将动态库更改为静态库,这使它正常工作。

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

有一些技巧可以克服这一点,例如使用线程区域设置存储,但通常您必须确保 DLL 通过单例传递,也许在主应用程序中制作单例,然后将其作为某种上下文对象传递。