gpt4 book ai didi

c++ - 如何派生出需要嵌套类模板类型的模板类?

转载 作者:行者123 更新时间:2023-11-28 06:12:03 25 4
gpt4 key购买 nike

我正在使用 OpenGL (C API) 并将一些东西封装在类中。基本上,调用 glGenX 会生成 GLuint,它们是实际创建的对象的句柄。当您清理时,您应该对这些句柄调用 glDeleteX

这意味着,对我来说,拥有一个类来保存这些(以及封装一些其他特定于它们的东西)并能够复制实例并传递它们,该类需要内部引用计数,以便它仅在没有更多引用时调用 glDeleteX

我现在已经完成了两次,我正在考虑第三堂课。我可以看到我正在制作的很多类(class)都需要这个;所以我想使用模板来简化它。

下面是原始类的示例,其引用计数仅在适当的时间调用 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;

这样外部用户只能使用引用计数的纹理。

关于c++ - 如何派生出需要嵌套类模板类型的模板类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31063013/

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