避免显式构造函数调用虚拟基类

Dre*_*wen 7 c++ com inheritance constructor virtual-inheritance

基本问题:是否可以避免必须显式调用每个虚拟基类的(非默认)构造函数?

背景:我正在开发围绕Windows COM对象的一些类型安全的C++包装器类.我目前的方法是有一个CBaseCOMWrapper类封装一个IUnknown对象进行引用计数.然后,我有一个CCOMWrapper模板类所继承CBaseCOMWrapper,它定义一个包装为特定COM类型(即IDXGIObject,ID3D11Device等).最后,单独的类从这些包装模板继承来提供实际的/额外的功能(即CDXGIObject,CD3D11Device).

例如,我有以下类(成员省略):

class CBaseCOMWrapper { };

template<typename T> // here, T should inherit from IUnknown
class CCOMWrapper : public virtual CBaseCOMWrapper { };

class CDXGIObject : public virtual CCOMWrapper<IDXGIObject> { };

template<>
class CCOMWrapper<IDXGIAdapter> : public virtual CCOMWrapper<IDXGIObject> { };

class CDXGIAdapter : public virtual CCOMWrapper<IDXGIAdapter> { };
Run Code Online (Sandbox Code Playgroud)

这是类型层次结构的对应图:

键入层次结构

左列是实际对象,中间列是瘦COM包装器,右列是实际COM对象.实线箭头表示继承,虚线箭头表示封装.

我使用模板特化CCOMWrapper来在中间提供父子关系.

问题:包装器类假定一个指向COM对象的非NULL(也就是有效)指针,所以我不能有一个默认的构造函数.因为层次结构充满了"钻石",所以大部分遗传都是虚拟的; 这意味着每个类的构造函数都必须调用构造函数.因此,在上面的例子中,构造函数CDXGIAdapter必须调用构造函数CCOMWrapper<IDXGIAdapter>,CDXGIObject,CCOMWrapper<IDXGIObject>,和CBaseCOMWrapper.随着层次结构的扩展(即ID3D11Predicate,继承链为4"链接"长),这意味着必须调用更多的构造函数.

可能的解决方案:理想情况下,我想使用宏来生成大多数基本构造函数调用,但是我必须为每个COM对象提供整个继承链; 对于不同长度的链,这将需要不同的宏.但是,最长的长度是4(我只使用DXGI,D3D11和D2D1),所以这不是不可能的.

那么我怎样才能避免必须调用所有构造函数?或者,有没有更好的方法来实现我想要做的事情?

Dre*_*wen 1

事实证明,对于我想要完成的事情,模板CCOMWrapper是不必要的。我只需要每个类提供一个采用相应 COM 对象类型的构造函数:

class CDXGIObject : public CCOMObject
{
public:
    CDXGIObject(IDXGIObject *obj);
};

class CDXGIFactory : public CDXGIFactory
{
public:
    CDXGIFactory(IDXGIFactory *obj);
};
Run Code Online (Sandbox Code Playgroud)

这消除了对虚拟继承的需要,因此我不需要再调用所有基本构造函数。