这是我在C ++中半个观察者模式的简化实现。 它没有编译,我有三个问题:
错误C2259:'MyClass':无法实例化抽象类1>
由于以下成员:1> “无效 IObservable :: addObserver(void *)':是抽象1>
e:_projects \ test \ test.cpp(9):见声明 'IObservable :: addObserver'1> “无效 IObservable :: removeObserver(void *)':是抽象1>
e:_projects \ test \ test.cpp(11):见声明 '的IObservable :: removeObserver'
“多重继承解决方案”我认为你使用得很好吗?我不希望IMyInterface
继承AObservable
,因为我希望IMyInterface
的实现者能够自己实现IObservable
,如果他们愿意的话。
有点无关,但正如我们所说的那样。我认为virtual void raiseChanged() final
比void raiseChanged()
更明确,以告诉实现者我不希望这被覆盖。除了性能影响之外,这样做有什么不利之处吗?
代码:
class IObservable
{
public:
virtual void addObserver(void *observer) = 0;
virtual void removeObserver(void *observer) = 0;
};
class AObservable : public IObservable
{
public:
AObservable()
: _observerCount(0)
{
}
virtual void addObserver(void *observer) final override
{
++_observerCount;
};
virtual void removeObserver(void *observer) final override
{
--_observerCount;
};
protected:
virtual void raiseChanged() final
{
// call all the observers
}
private:
// We just count instead of the data structure
int _observerCount;
};
class IMyInterface : public virtual IObservable
{
public:
virtual void someMethod() = 0;
};
class AMyClass : public IMyInterface,
public virtual AObservable
{
public:
virtual void someMethod() = 0;
};
class MyClass : public AMyClass
{
public:
virtual void someMethod() final override
{
//does something
raiseChanged();
}
};
int main(int argc, char* argv[])
{
MyClass cla;
cla.someMethod();
return 0;
}
答案 0 :(得分:1)
实际上, 实际上在这里没有多重继承。你拥有的是一个继承抽象类和实现接口的类。 (在java中,这将更加明显)
这不会触发虚拟继承的任何问题,即"The dreaded diamond-shaped inheritance",只要你避免自己好。
您不会通过声明函数final来支付任何进一步的性能开销。因为它已经是虚拟的。作为一般规则,你应该总是三思而后行,因为你不应该总结你的用户如何扩展你的类。但如果你有一个很好的理由让它成为最终的,请继续。
答案 1 :(得分:0)
复杂继承问题通常可以通过使用组合而不是继承来解决。在您的情况下,您可以将AObservable
视为实现而不是超类:
class AMyClass : public IMyInterface
{
struct : AObservable {
// Make the protected raiseChanged method public so we can use it.
using AObservable::raiseChanged;
} impl;
public:
virtual void someMethod() = 0;
virtual void addObserver(void *observer) override
{
impl.addObserver(observer);
}
virtual void removeObserver(void *observer) override
{
impl.removeObserver(observer);
}
protected:
void raiseChanged() { impl.raiseChanged(); }
};