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 */ }
};
这导致以下层次结构:
IDerived
和 CBase
实际上都继承自 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
.
我想知道在 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 */ }
};
这导致以下层次结构:
IDerived
和 CBase
实际上都继承自 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
.