我正在使用OpenGL(C API),并将一些东西封装在类中。基本上,对glGenX的调用会生成GLuint,这些cc是创建的实际事物的句柄。清理时,应在这些句柄上调用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;};这个想法是内部的glDeleteX类对于类Data可能只需要一个GLuint句柄,但是对于另一种类型,它可能需要三个不同的句柄。因此,这就是内部存在Texture的原因。现在,我有问题。这是我现在从这个模板化的类派生的原始类: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:};如何定义基类tuple的析构函数?到目前为止,我已经尝试过这样做:稍微更改基类:template<class DataType, typename... Ts>class ReferenceCountedObject{ /* ... */protected: DataType* m_data;};因此,通过这种方式,您可以提供DataType并仅覆盖虚拟析构函数: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)); }; };}但是我无法使用Data实例化ReferenceCountedObject,因为Texture::TData是我要定义的一部分。如何正确执行此操作?我承认我可能会以完全不正确的方式进行此操作。 (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 为什么不只使用shared_ptr?该引用也算在内,并且传递起来更简单。您的类只需要处理纹理的分配和释放,shared_ptr会在适当的时候进行引用计数和自动删除。另外,这使您可以免费使用弱指针。您可以定义内部的Texture类,然后执行typedef std::shared_ptr<internal::Texture> Texture;这样外部用户只能使用参考计数的Texture。 (adsbygoogle = window.adsbygoogle || []).push({});