2012-04-05 20 views
0

我有两个单身,第一个的头看起来像这样(我省略了不相关的Singleton模式的所有内容):这个单身模式为什么不起作用?

#ifndef TEXTUREMANAGER_DEFINED_H 
#define TEXTUREMANAGER_DEFINED_H 
class FontManager; 
class TextureManager 
{ 
private: 
    static TextureManager *instance; 
    TextureManager(); 
public: 
    FontManager *fontManager; 
    static TextureManager* Instance(); 
}; 

#endif 

并在实施,这是Instance()方法(和实例静态成员的初始化):

#include "FontManager.h" 
TextureManager * TextureManager::instance = 0; 
TextureManager* TextureManager::Instance() 
{ 
    if (instance==0) 
     instance=new TextureManager; 
    return instance; 
} 

这是构造函数:

TextureManager::TextureManager() 
{ 
    fontManager=FontManager::Instance(); 
} 

第二单的(FontM anager)的设计完全一样,但是不是FontManager指针具有TextureManager指针,而是在其构造函数中使用TextureManager :: Instance()初始化该指针。 这应该像这样工作:TextureManager首先实例化(当程序启动时),并且在它的构造函数实例中第一次调用FontManager单例调用FontManager :: Instance()。在它的构造函数中,FontManager使用TextureManager :: Instance()将其指针指定给TextureManager,并且此方法返回已存在的TextureManager实例。对?

但是,而不是程序进入无限循环,因为(我不知道为什么)Instance()方法总是创建一个新的实例。我喜欢if (instance==0)总是评估为真。

+0

你为什么需要这个fontManager?它也是单例...所以你可以稍后使用它...不在纹理管理器的构造函数中 – fen 2012-04-05 09:15:22

回答

7

因为你写了一个无限循环,其中TextureManager的构造函数调用的FontManager构造函数,然后调用的TextureManager构造....等等。

因为构造函数必须在分配静态变量之前完成,所以最终会在此循环中完成。

+0

非常感谢你,我犯了一个非常愚蠢的错误。我将从构造函数中取出指针赋值。我会尽快接受答案 – XaitormanX 2012-04-05 09:18:37

+0

@XaitormanX使用'Singleton's初始化错误的顺序。呸!只需制作一个并传递给它。你不需要它是一个只有一个实例的全局。这只是一种便利,这意味着你不会仔细考虑你的设计(在这种情况下,初始化的顺序)。 – 2012-04-05 10:22:06

0

对于单例,您不要将构造函数作为公共接口公开。取而代之的是,你有一个单独的静态实例检索成员函数和一个私人的构造函数:

class Foo 
{ 
    Foo() { /* ... */ } 
public: 
    static Foo & get() 
    { 
     static Foo instance; // uses private constructor 
     return instance; 
    } 
}; 

或者到静态成员,你还可以做你的指针伎俩,但你应该有一个static std::unique_ptr<Foo>以确保适当的销毁,该计划结束。