请考虑:
IReferenceCounting是一个纯抽象类,使用方法AddRef和RemoveRef
virtual void AddRef() noexcept = 0;
virtual void RemoveRef() noexcept = 0;
我没有建立这个类,也不能改变它。
现在我有另一个类,我构建了一个名为ISoundComponent的类,它继承自IReferenceCounting。类ISoundComponent也是抽象的(一开始它不包含AddRef或Release的定义)。
由于每个继承自IReferenceCounted的组件都需要实现AddRef和RemoveRef,因此存在ReferenceCountedImpl,它继承自IReferenceCounted。我没有建立这个类,我无法改变它。
最后,我有另一个我构建的类,比如SoundDiagnostics,它继承自ISoundComponent和ReferenceCountedImpl
很多人已经看过了 - 我有钻石继承问题。通过不提供我自己的AddRef和RemoveRef,而是使用ReferenceCountedImpl,意味着我需要ISoundComponent和ReferenceCountedImpl来虚拟地继承IReferenceCounted ...正确吗?
不幸的是我无法编辑只有ISoundComponent的ReferenceCountedImpl。这是因为IReferenceCounting和ISoundComponent存在于我们的代码库中的许多项目中,但是ReferenceCountedImpl只存在于一个项目中(SoundDiagnostics存在于同一个项目中)。这是有道理的,因为项目可以决定它如何实现IReferenceCounting,我们应该能够在该项目的不同类中重用它。
不幸的是,因为我不能去编辑ReferenceCountedImpl,所以我无法构建这个,因为钻石继承问题(SoundDiagnostics不知道是否要调用ReferenceCountedImpl :: AddRef或ISoundComponent :: AddRef)。
我觉得我正在咆哮错误的树,错过了一些明显的东西,陷入了虚拟继承的细节和/或我的设计搞砸了。代码库组织应该对此问题不可知。谁能给我一些关于如何构建它的指导?我认为没有从IReferenceCounted虚拟继承的ReferenceCountedImpl是解决方案 - 例如执行此操作时需要考虑性能原因。
有兴趣学习如何解决这个问题。
编辑:
// available across all projects in code base
class IReferenceCounted
{
virtual void AddRef() = 0;
virtual void RemoveRef() = 0;
};
// available across a few select projects in the codebase (ones that wish to use some kind of sound component)
class ISoundComponent : public virtual IReferenceCounted
{
virtual void Play() const = 0;
};
// available within one specific project, SoundDiagnostics. I cannot modify this
class ReferenceCountedImpl : public IReferenceCounted
{
void AddRef() override
{
m_refcount++;
}
void RemoveRef() override
{
if (--m_refcount == 0)
{
delete this;
}
}
int m_refcount = 0;
};
// available within one specific project, SoundDiagnostics.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void RunDiagnostics()
{
}
};
// function within my SoundDiagnostics project
int main()
{
SoundDiagnostics soundDiagnostics;
return 0;
}
试图编译这将产生
不允许使用抽象类类型“SoundDiagnostics”的对象: 纯虚函数“IReferenceCounted :: AddRef”没有覆盖纯虚函数“IReferenceCounted :: RemoveRef”没有覆盖
如果ReferenceCountedImpl虚拟地从IReferenceCounted继承,那么此代码将成功编译。
我试图将你的描述变成代码。有用。
class IReferenceCounting {
public:
virtual void AddRef() const noexcept = 0;
virtual void RemoveRef() const noexcept = 0;
};
class IComponentPublicHeader :public virtual IReferenceCounting {};
class ReferenceCountedImpl :public virtual IReferenceCounting {
public:
void AddRef() const noexcept override {};
void RemoveRef() const noexcept override {};
};
class MyAmazingClass : IComponentPublicHeader, ReferenceCountedImpl {
MyAmazingClass() {
AddRef();// ReferenceCountedImpl::AddRef
}
};
更新:我读了你的代码片段。如果AddRef和RemoveRef是公共的,你可以尝试像这样实现你的类。
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void AddRef() override
{
ReferenceCountedImpl::AddRef();
}
void RemoveRef() override
{
ReferenceCountedImpl::RemoveRef();
}
void RunDiagnostics()
{
}
};
如果AddRef和RemoveRef是私有的,那么让ISoundComponent不继承IReferenceCounted。
class ISoundComponent
{
virtual void Play() const = 0;
};