0

我有两个单例,第一个的标题看起来像这样(我省略了与单例模式无关的所有内容):

#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();
}

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

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

4

2 回答 2

7

因为您编写了一个无限循环,其中的构造函数TextureManager调用其构造函数FontManager,然后调用TextureManager.... 的构造函数,依此类推。

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

于 2012-04-05T09:14:03.653 回答
0

对于单例,您不会将构造函数公开为公共接口。相反,您有一个单独的静态实例检索成员函数和一个私有构造函数:

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

作为静态成员的替代方法,您也可以使用指针技巧,但是您应该static std::unique_ptr<Foo>确保在程序结束时正确销毁。

于 2012-04-05T09:19:35.370 回答