Обратите внимание:
IReferenceCounting - чистый абстрактный класс с методами AddRef и RemoveRef
virtual void AddRef() noexcept = 0;
virtual void RemoveRef() noexcept = 0;
Я не создавал этот класс и не могу его изменить.
Теперь у меня есть другой класс, который я создал, который называется ISoundComponent, который наследуется от IReferenceCounting.Класс ISoundComponent также является абстрактным (для начала он не содержит определения для AddRef или Release).
Поскольку каждый компонент, который наследуется от IReferenceCounting, должен будет реализовывать AddRef и RemoveRef, существует ReferenceCountingImpl, который наследует отIReferenceCounted.Я не создавал этот класс и не могу его изменить.
Наконец, у меня есть еще один класс, который я создал, например SoundDiagnostics, который наследуется от ISoundComponent и ReferenceCountingImpl
Многие из вас уже видели его- У меня проблема с наследованием бриллиантов.Поскольку я не предоставляю свои собственные AddRef и RemoveRef и вместо этого использую ReferenceCountingImpl, мне нужно, чтобы ISoundComponent и ReferenceCountingImpl унаследовали виртуально от IReferenceCounting ... правильно?
К сожалению, я не могу редактировать ReferenceCountingImpl только ISoundComponent.Это связано с тем, что IReferenceCounting и ISoundComponent живут во многих проектах в нашей кодовой базе, а ReferenceCountingImpl живет только в одном проекте (живет тот же проект SoundDiagnostics).Это имеет смысл, поскольку проект может принять решение о том, как он хочет реализовать IReferenceCounting, и мы должны иметь возможность повторно использовать его внутри различных классов в этом проекте.
К сожалению, поскольку я не могу пойти и отредактировать ReferenceCountingImpl, яне может построить это из-за проблемы наследования алмазов (SoundDiagnostics не будет знать, вызывать ли ReferenceCountingImpl :: AddRef или ISoundComponent :: AddRef).
Мне кажется, что я лаю не на том дереве, упускаю что-то очевидное, попадаю в детали виртуального наследования и / или мой дизайн испорчен.Организация кодовой базы должна быть независимой от этой проблемы.Кто-нибудь может дать мне несколько советов о том, как это должно быть спроектировано?Я не думаю, что ReferenceCountingImpl, унаследованное фактически от IReferenceCounting, является решением - например, существуют причины производительности, которые следует учитывать при выполнении этого.
Заинтересованы, чтобы узнать, как справиться с этим.
РЕДАКТИРОВАТЬ:
// 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" не разрешено:
чисто виртуальная функция "IReferenceCounting :: AddRef" не имеет переопределителя чисто виртуальногофункция "IReferenceCounting :: RemoveRef" не имеет переопределения
Если ReferenceCountingImpl фактически наследует от IReferenceCounts, этот код успешно компилируется.