gpt4 book ai didi

c++ - 具有模板化类型的动态类型单例。这是一种可行的方法吗? [提供的解决方案]

转载 作者:行者123 更新时间:2023-11-30 04:08:33 26 4
gpt4 key购买 nike

我目前正在开发我自己的引擎,特别是图形界面,并试图让它能够在 DirectX 和 openGL 渲染之间进行选择。为此,我想要一个纹理管理器单例(我习惯于使用它的标准实现)。但是在这种情况下,我希望能够在抽象功能的同时选择实例的动态类型。到目前为止,这是我的实现:

template <typename T>
class TextureManagerType
{
public:

virtual ~TextureManagerType() = 0 {}


T* GetTexture(TEXTURE_ID texID)
{
std::map<TEXTURE_ID, T*>::const_iterator it = m_textures.find(texID);
if(it != m_textures.end())
{
return (*it)->second;
}
else
{
assert(0);
return 0;
}
}

bool Load(const std::string& texturePaths)
{
File f;
if(!f.Open(texturePaths))
{
ReportError("Fatal error! Could not open: " + texturePaths);
return false;
}

std::string str;

while(!f.EndOf())
{
if(!f.GetString(&str))
{
ReportError("Warning: Unexpected end of file in texturepaths file: " + texturePaths);
}
LoadTexture(str);
}

return true;
}

virtual T* LoadTexture(const std::string& texturePath) = 0;

protected:
std::map<TEXTURE_ID, T*> m_textures;
};


//Uncopyable is a base class with a disabled copy constructor
class TextureManager : public Uncopyable
{
private:
TheTextureManager();

public:
//T here is underlined in all three mentions as it is undefined
static TextureManagerType<T>* Instance()
{
return m_pInstance;
}
static void SetDynamicType(TextureManagerType<T>* type)
{
m_pInstance = type;
}
static TextureManagerType<T>* m_pInstance;


//static TexManagerType* Instance()
//{
// return m_pInstance;
//}
//static void SetDynamicType(TexManagerType* type)
//{
// m_pInstance = type;
//}
//static TexManagerType* m_pInstance;

};

//Named to be consistent with normal singletons
typedef TextureManager TheTextureManager;

如您所见,我牺牲了单例的 RAII 红利,需要将 m_pInstance 指针初始化为 null。

//I want the singleton once set, to be able to be accessed thusly:
TheTextureManager::Instance()->DoTextureFunction();

我不希望每种类型的 TextureManager 都使用单例,因为我希望能够在保持全局可访问性的同时控制每个派生管理器的生命周期。目前我的系统根本不工作,因为 TextureManager::Instance 的返回类型需要知道不可访问的模板化类型。

我尝试在 TextureManager 中嵌套 TextureManagerType 但这意味着每次调用纹理管理器需要所需的类型作为模板参数,这有点违背了抽象这一点。

请帮助男孩和女孩,请在您的评论中提出建设性意见。请询问我是否遗漏了关键/所有细节。大脑太累了,现在无法思考。谢谢

最佳答案

您可以为您的 TextureManagerType 定义一个抽象的、非模板化的接口(interface),并使用它来引用纹理管理器单例对象中的纹理管理器实现。
为此,您还需要 Texture 对象的多态表示,它可以像 union 类型或抽象基类一样简单,具有针对不同具体纹理类型的派生类。
它可能看起来像这样:

union TextureContainer {
OpenGLTexture* oglt;
DirectXTexture* dxt;
};

class TextureManagerTypeBase
{
public:

virtual ~TextureManagerType() = 0;
virtual TextureContainer GetTexture(TEXTURE_ID texID) = 0;
virtual TextureContainer LoadTexture(const std::string& texturePath) = 0;

//this looks like it only refers to other public
// methods, so it's staying here
virtual bool Load(const std::string& texturePaths)
{
...
}
};

template <typename T>
class TextureManagerType : public TextureManagerTypeBase
{
public:
// pretty much the same as before
// minus Load wich is defined in the base class
// plus wrapping T into a TextureContainer
...
};


//Uncopyable is a base class with a disabled copy constructor
class TextureManager : public Uncopyable
{
private:
TheTextureManager();

public:
//T here is underlined in all three mentions as it is undefined
static TextureManagerTypeBase* Instance()
{
return m_pInstance;
}
static void SetDynamicType(TextureManagerTypeBase* type)
{
m_pInstance = type;
}
static TextureManagerTypeBase* m_pInstance;
};

这有点粗糙,但希望您能理解。

关于c++ - 具有模板化类型的动态类型单例。这是一种可行的方法吗? [提供的解决方案],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21769034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com