c++ COM接口继承
Posted
技术标签:
【中文标题】c++ COM接口继承【英文标题】:c++ COM interface inheritance 【发布时间】:2017-07-23 10:50:16 【问题描述】:我想知道在 COM 应用程序中通过继承实现代码重用的最佳方法是什么。
问题
据我了解,C++ 的虚拟继承模型不能在 COM 环境中使用,因为它不是语言独立的。
在纯 C++ 中,类层次结构可能如下所示:
interface IBase
virtual void BaseMethod() = 0;
;
interface IDerived : virtual IBase
virtual void DerivedMethod() = 0;
;
class CBase : public virtual IBase
public:
virtual void BaseMethod() override /* Do something */
;
class CDerived : public IDerived, public CBase
public:
virtual void DerivedMethod() override /* Do something */
;
这会产生以下层次结构:
IDerived
和 CBase
都实际上继承自 IBase
。
由于虚拟继承在 COM 中不可用,因此类层次结构更倾向于如下所示:
interface IBase
virtual void BaseMethod() = 0;
;
interface IDerived : IBase
virtual void DerivedMethod() = 0;
;
class CBase : public IBase
public:
virtual void BaseMethod() override /* Do something */
;
class CDerived : public IDerived, public CBase
public:
virtual void DerivedMethod() override /* Do something */
;
这会产生以下层次结构:
乍一看,IBase
的歧义似乎有问题。这可以通过实现IUnknown::QueryInterface
方法轻松解决。
真正的问题是,CDerived
如何从CBase
继承IBase
的实现方法,即CBase::BaseMethod
?
在虚拟继承的情况下,CBase::BaseMethod
可以通过显性继承,但如果没有虚拟继承,这不会发生:在CDerived
中,定义了方法CBase::IBase::BaseMethod
,但没有定义方法IDerived::IBase::BaseMethod
,导致在 CBase
类中仍然是抽象的,因此不适合实例化。
解决此问题的一种方法是再次覆盖 CDerived
中的方法 BaseMethod
:
class CDerived : public IDerived, public CBase
public:
virtual void BaseMethod() override CBase::BaseMethod();
virtual void DerivedMethod() override /* Do something */
;
这对性能有影响吗?有没有更好的方法来实现我想要的? CDerived
中函数的重复覆盖不是破坏了继承的整个想法吗?
【问题讨论】:
这个问题是基于一个非常错误的假设。 COM 通过只看到接口的客户端代码来实现语言独立性。该实现是完全不可见的。这允许你做任何你想做的事情来实现接口,实际上使用非虚拟多重继承是样板方法。对于所有已实现的接口,只有一个函数来实现 QueryInterface、AddRef、Release 正是您想要的。任何 COM 基础教程都会向您展示如何做到这一点。 【参考方案1】:ATL 广泛使用如下技术:
template <typename Itf>
class IBaseImpl : public Itf
public:
void BaseMethod() override;
;
class CBase : public IBaseImpl<IBase> ;
class CDerived : public IBaseImpl<IDerived>
public:
void DerivedMethod() override;
;
现在你有了直线继承:IBase
IDerived IBaseImpl<IDerived> CDerived。
【讨论】:
以上是关于c++ COM接口继承的主要内容,如果未能解决你的问题,请参考以下文章