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

7

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

背景:我正在为Windows COM对象编写一些类型安全的C ++包装器类。我的当前方法是拥有一个CBaseCOMWrapper类,它封装了一个IUnknown对象以进行引用计数。然后,我有一个CCOMWrapper模板类,该类继承自CBaseCOMWrapper,它定义了特定COM类型的包装器(即IDXGIObjectID3D11Device等)。最后,单独的类从这些包装器模板继承以提供实际/额外的功能(即CDXGIObjectCD3D11Device)。

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

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> { };

这是类型层次结构的相应图表:
左列是实际对象,中间列是薄的COM包装器,右列是实际的COM对象。实线箭头表示继承关系,虚线箭头表示封装关系。
我使用CCOMWrapper的模板特化来提供中间部分的父子关系。
问题:包装类假定非NULL(即有效)指向COM对象的指针,因此我不能有默认构造函数。由于层次结构充满了“菱形”,大部分继承都是虚拟的;这意味着每个类的构造函数必须调用构造函数。因此,在上面的示例中,CDXGIAdapter的构造函数必须调用CCOMWrapper、CDXGIObject、CCOMWrapper和CBaseCOMWrapper的构造函数。随着层次结构的扩展(即ID3D11Predicate的继承链长度为4个“链接”),这意味着必须调用更多的构造函数。
可能的解决方案:理想情况下,我希望使用宏来生成大部分基础构造函数调用,但我必须为每个COM对象提供整个继承链;这将需要不同长度的链的不同宏。然而,最长的长度是4(我只使用DXGI、D3D11和D2D1),所以这并不是不可能的。
那么我如何避免调用所有构造函数呢?或者,有没有更好的方法来实现我想做的事情?

对于任何含糊或奇怪的陈述,我表示歉意;我是在历史课上写这个的:P - Drew McGowen
2
C++封装类的历史? - Paul Evans
1个回答

1
事实证明,对于我想要实现的目标,CCOMWrapper 模板是不必要的。我只需要每个类提供一个接受相应 COM 对象类型的构造函数即可:
class CDXGIObject : public CCOMObject
{
public:
    CDXGIObject(IDXGIObject *obj);
};

class CDXGIFactory : public CDXGIFactory
{
public:
    CDXGIFactory(IDXGIFactory *obj);
};

这样可以消除虚继承的需要,因此我不再需要调用所有基类构造函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接