我正在使用OpenGL(C API)並在類中封裝了一些東西。基本上調用glGenX
生成GLuint
s是創建實際事物的句柄。清理時,應在這些手柄上撥打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;
};
這是我嘗試在templatizerating它:
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));
};
};
}
但我不能實例化ReferenceCountedObject
與Texture::TData
,因爲TData
是我想要定義的一部分。
我該如何正確地做到這一點?我承認我可以用完全不正確的方式解決這個問題。
我知道我可以。事實上,這正是我之前所做的。但我更願意弄清楚如何做到上述。 – NeomerArcana
而不是參數化您的refcounted類的數據類型,通過包含類(它具有所有必要的獲取/發佈邏輯)對其進行參數化。你會發現實現起來要容易得多。 – nneonneo