C++ COM接口继承

c++ COM interface inheritance

我想知道在 COM 应用程序中通过继承实现代码重用的最佳方法是什么。

问题

据我了解,C++ 的虚拟继承模型不能用于 COM 环境,因为它不是语言独立的。

在纯 C++ 中,class 层次结构可能如下所示:

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 */ }
};

这导致以下层次结构:

IDerivedCBase 实际上都继承自 IBase

由于虚拟继承在 COM 中不可用,class 层次结构看起来像这样:

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 不是,导致 class CBase 仍然是抽象的,因此不符合实例化条件。

解决此问题的一种方法是再次覆盖 CDerived 中的方法 BaseMethod

class CDerived : public IDerived, public CBase {
public:
    virtual void BaseMethod() override { CBase::BaseMethod(); }
    virtual void DerivedMethod() override { /* Do something */ }
};

这对性能有影响吗?有没有更好的方法来实现我想要的? CDerived 中函数的重复覆盖是否破坏了继承的整个思想?

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.