C++ 中纹理数据指针的联合
Union of texture data pointers in C++
我从不同来源捕获纹理数据,其中数据在 BYTE* 或 ID3D11Texture2D COM 指针中,因此我尝试制作一个包含以下联合类型集合的 STL 容器。
_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D, __uuidof(ID3D11Texture2D));
union TextureData
{
ID3D11Texture2DPtr m_tex2D;
BYTE* m_byte;
};
但是当我只编译上面的声明而不使用 STL 容器的联合类型时,我看到以下警告:
warning C4624: '....::TextureData': destructor was implicitly defined as deleted
谁能告诉我在宣布这个联盟时我应该注意什么?
编辑:
我本来打算这样用的,但是在使用之前出现了编译警告:
std::array< std::tuple<< DXGI_FORMAT, TextureData>>, 4>;
编辑 2:
我发现如果我像下面这样使用,警告不会显示:
union TextureData
{
ID3D11Texture2D* m_tex2D;
BYTE* m_byte;
};
If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.
如果您还记得 C++ 不跟踪联合 的活动成员,那么这条规则就很有意义,因此当联合被析构时,它不知道析构函数呼叫哪个成员。当然,如果所有成员都有平凡的析构函数,这没有关系。
来自_COM_SMARTPTR_TYPEDEF documentation:
A smart pointer is usually referenced by the typedef definition provided by the _COM_SMARTPTR_TYPEDEF macro. This macro takes an interface name and the IID and declares a specialization of _com_ptr_t with the name of the interface plus a suffix of Ptr.
来自 _com_ptr_t 的来源:
// If we still have an interface then Release() it. The interface
// may be NULL if Detach() has previously been called, or if it was
// never set.
//
~_com_ptr_t() throw()
{
_Release();
}
如您所见,_com_ptr_t
有一个非平凡的析构函数,因此您需要向联合体添加一个显式析构函数。这是您需要手动调用对象的析构函数的罕见情况之一。像这样:
union TextureData
{
ID3D11Texture2DPtr m_tex2D;
BYTE* m_byte;
~TextureData() {
if (/* m_tex2D is the active member */)
m_tex2D.~_com_ptr_t();
}
};
请注意,由于TextureData
不跟踪其活跃成员,因此您需要自行确定m_text2D
是否活跃。
您可以使用的另一种方法是使用 std::variant
而不是原始联合。与联合相反,变体 确实 跟踪活动成员("alternative")并为您调用适当的析构函数。
我从不同来源捕获纹理数据,其中数据在 BYTE* 或 ID3D11Texture2D COM 指针中,因此我尝试制作一个包含以下联合类型集合的 STL 容器。
_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D, __uuidof(ID3D11Texture2D));
union TextureData
{
ID3D11Texture2DPtr m_tex2D;
BYTE* m_byte;
};
但是当我只编译上面的声明而不使用 STL 容器的联合类型时,我看到以下警告:
warning C4624: '....::TextureData': destructor was implicitly defined as deleted
谁能告诉我在宣布这个联盟时我应该注意什么?
编辑:
我本来打算这样用的,但是在使用之前出现了编译警告:
std::array< std::tuple<< DXGI_FORMAT, TextureData>>, 4>;
编辑 2:
我发现如果我像下面这样使用,警告不会显示:
union TextureData
{
ID3D11Texture2D* m_tex2D;
BYTE* m_byte;
};
If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.
如果您还记得 C++ 不跟踪联合 的活动成员,那么这条规则就很有意义,因此当联合被析构时,它不知道析构函数呼叫哪个成员。当然,如果所有成员都有平凡的析构函数,这没有关系。
来自_COM_SMARTPTR_TYPEDEF documentation:
A smart pointer is usually referenced by the typedef definition provided by the _COM_SMARTPTR_TYPEDEF macro. This macro takes an interface name and the IID and declares a specialization of _com_ptr_t with the name of the interface plus a suffix of Ptr.
来自 _com_ptr_t 的来源:
// If we still have an interface then Release() it. The interface
// may be NULL if Detach() has previously been called, or if it was
// never set.
//
~_com_ptr_t() throw()
{
_Release();
}
如您所见,_com_ptr_t
有一个非平凡的析构函数,因此您需要向联合体添加一个显式析构函数。这是您需要手动调用对象的析构函数的罕见情况之一。像这样:
union TextureData
{
ID3D11Texture2DPtr m_tex2D;
BYTE* m_byte;
~TextureData() {
if (/* m_tex2D is the active member */)
m_tex2D.~_com_ptr_t();
}
};
请注意,由于TextureData
不跟踪其活跃成员,因此您需要自行确定m_text2D
是否活跃。
您可以使用的另一种方法是使用 std::variant
而不是原始联合。与联合相反,变体 确实 跟踪活动成员("alternative")并为您调用适当的析构函数。