具有模板化类型的动态类型Singleton.这是可行的方法吗?[提供的解决方案]
Dynamic Type Singleton with templated types. Is this a viable approach? [Solution Provided]
我目前正在开发自己的引擎,特别是图形界面,并试图使其能够在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
定义一个抽象的、非模板化的接口,并使用它来引用纹理管理器singleton对象中的纹理管理器实现
为了做到这一点,您还需要纹理对象的多态表示,它可以是简单的联合类型或抽象基类,具有不同具体纹理类型的派生类
可能都是这样的:
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++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 调用具有未标识类型的类的方法
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 我的模板类方法返回错误类型?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 构造智能点数据类型以及普通数据类型的通用方法
- 如何在没有实例的情况下获取非静态方法的类型?
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 使用类型id运算符的最佳替代方法
- Java 调用 dll 字符串返回类型方法
- C++ 如何绑定和调用模板化类型方法
- 将返回类型推断为模板参数类型方法
- 返回true的模板化类型方法是在条件中进行优化的良好候选者