如何派生需要嵌套类的模板类型的模板类
How to derive a template class that needs a template type of a nested class?
我正在使用OpenGL(C API(并将一些东西封装在类中。基本上,对glGenX
的调用会生成GLuint
,这些是实际创建的事物的句柄。清理时,应调用这些句柄上的glDeleteX
。
来保存这些(以及封装一些特定于它们的其他东西(并能够复制实例并传递它们,该类需要内部引用计数,以便它仅在没有更多引用时才调用glDeleteX
。
我已经做了两次了,我正在看第三节课。我可以看到我正在制作的很多课程都需要这个;所以我想使用模板来简化它。
下面是原始类的示例,其中引用计数仅在适当的时间调用glDeleteX
:
class Texture
{
public:
Texture(const GLuint texture) : m_data(new Data(texture)) {}
Texture(const Texture& t) : m_data(t.m_data) { ++m_data->m_count; }
Texture(Texture&& t) : m_data(t.m_data) { ++m_data->m_count; }
~Texture() { if(--m_data->m_count == 0) delete m_data; }
void Bind(GLenum target, GLint location) const { /* do some stuff */;
void Release() const { /* do some stuff */
GLuint GetTexture() const { return m_data->m_texture; }
private:
class Data
{
public:
Data(const GLuint texture) : m_count(1), m_texture(texture) {}
Data(const Data& data) : m_count(1), m_texture(data.m_texture) {}
~Data() { glDeleteTexture(1,&m_texture); }
GLuint m_texture;
unsigned int m_count;
};
Data* m_data;
};
这是我尝试将其模板化:
template<typename... Ts>
class ReferenceCountedObject
{
public:
ReferenceCountedObject(const Ts... args)
:
m_data(new Data(args...))
{}
ReferenceCountedObject(const ReferenceCountedObject& h)
:
m_data(h.m_data)
{
++m_data->m_count;
}
ReferenceCountedObject(ReferenceCountedObject&& h)
:
m_data(h.m_data)
{
++m_data->m_count;
}
virtual ~ReferenceCountedObject()
{
if(--m_data->m_count == 0)
delete m_data;
}
protected:
class Data
{
public:
Data(const Ts... args)
:
m_count(1),
m_dataMembers(args...)
{
}
Data(const Data& data)
:
m_count(1),
m_dataMembers(data.m_dataMembers)
{
}
virtual ~Data()
{
std::cout << "deleting base" << std::cout;
}
std::tuple<Ts...> m_dataMembers;
unsigned int m_count;
};
Data* m_data;
};
这个想法是,内部 Data
类可能只需要一个GLuint
句柄用于类Texture
,但对于另一种类型,它可能需要三个不同的句柄。所以,这就是为什么有内部tuple
。
现在,我遇到了问题。这是我现在从这个模板化类派生的原始类:
class Texture : public ReferenceCountedObject<GLuint>
{
public:
Texture(GLuint texture) : ReferenceCountedObject(texture) {}
Texture(const Texture& t) : ReferenceCountedObject(t) {}
Texture(Texture&& t) : ReferenceCountedObject(t) {}
void Bind(GLenum target, GLint location) const { /* does that stuff */}
void Release() const { /* does that stuff */ }
GLuint GetTexture() const { return std::get<0>(m_data->m_dataMembers); }
protected:
};
如何定义基类Data
的析构函数?到目前为止,我已经尝试这样做:
稍微更改基类:
template<class DataType, typename... Ts>
class ReferenceCountedObject
{
/* ... */
protected:
DataType* m_data;
};
因此,通过这种方式,您可以提供数据类型并覆盖虚拟析构函数:
class Texture : public ReferenceCountedObject<Texture::TData,GLuint>
{
/* ... */
protected:
class TData : public ReferenceCountedObject::Data
{
public:
~TData()
{
std::cout << "deleting derived" << std::cout;
glDeleteTextures(1,&std::get<0>(m_dataMembers));
};
};
}
但我不能用Texture::TData
实例化ReferenceCountedObject
TData
因为这是我试图定义的一部分。
我怎样才能正确地做到这一点?我承认我可能以一种完全不正确的方式去做这件事。
为什么不直接使用shared_ptr
?这也是引用计算,并且传递起来更简单。您的类只需要处理分配和释放纹理,shared_ptr会在正确的时间进行重新计数和自动删除。另外,这使您可以免费使用弱指针。
您可以定义内部纹理类,然后执行
typedef std::shared_ptr<internal::Texture> Texture;
以便外部用户仅使用引用计数纹理。
相关文章:
- CRTP:为什么获得嵌套类型和派生类的嵌套方法有区别
- 为什么在VS2015中模板相关的嵌套类型名称中不需要typename关键字?
- 为什么嵌套类型的基类不需要"typename"?
- 如何在C++中的另一个模板函数中使用属于模板化类的嵌套类型?
- 保持嵌套类型的挥发性
- 具有嵌套类型的类的概念
- 将嵌套类型的类分开为标题和源
- 如何解决C++嵌套类型的循环依赖关系
- 在 C++11 中,从私有嵌套类型继承是否合法?
- C++ 递归嵌套类型和名称注入
- 如何定义一个模板类函数,该函数在类外的签名中具有嵌套类型的模板参数
- 访问模板参数T的嵌套类型,即使T是指针
- 为什么reverse_iterator双重定义其嵌套类型
- 嵌套类型:结构与类
- 如何对嵌套类型执行部分模板专用化
- 如何解析可选的嵌套类型,如 std::allocator_traits
- 模板和嵌套类型查找
- 在 c++ 中显示嵌套类型定义的最基本类型声明
- 无法推断出嵌套类型的模板函数
- C++使用别名访问嵌套类型(使用 vs typedef)