多重继承观察者模式在C+中的实现+; 这是C++中半观测器模式的简化实现。 它没有编译,我有三个问题: 为了编译它,我必须做什么?错误是:

多重继承观察者模式在C+中的实现+; 这是C++中半观测器模式的简化实现。 它没有编译,我有三个问题: 为了编译它,我必须做什么?错误是:,c++,multiple-inheritance,final,observers,C++,Multiple Inheritance,Final,Observers,错误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”

错误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()
    更明确,目的是告诉实现者我不希望覆盖它。这样做除了对性能有一点影响外,还有什么缺点吗

  • 代码:

  • 实际上,这里并没有多重继承。您拥有的是一个继承抽象类并实现接口的类。(在java中,这将更加明显)

    这不会引发虚拟继承的任何问题,也就是说,只要你避免你是好的

  • 通过声明函数final,您不必再支付任何性能开销。因为它已经是虚拟的了。一般来说,在将方法设置为final时,您应该三思而后行,因为您不应该概括用户如何扩展您的类。但如果你有很好的理由让它成为最终版本,那就继续吧


  • 复杂的继承问题通常可以通过使用组合而不是继承来解决。在您的情况下,可以将
    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(); }
    };
    

    您在这里实现的奇怪观察者模式。通常,您有一个“可观察的”和多个“观察者”,可以添加到一个可观察的。然后,被观察者可以调用虚拟函数来通知观察者。请参阅:对所有编辑感到抱歉,在子类化之后,它不再编译。问题也主要是关于多重继承,而不是观察者模式,所以我也改变了这一点。从IMyInterfaceYes dari中删除对IObservable的继承,但我希望IMyInterface的每个实现也实现IObservable(通过契约).Ye但现在你从IOobservable继承了2次,而IOobservable的纯抽象函数只从AOObservable定义,而不是从IMyInterface定义。我知道这里没有“坏”diamont形状,因为我做了一些在Java和C#中更常见的事情。钻石的顶部和一边是“接口”,但在C++中仍然是类。这就是为什么我认为我需要继承链上的“virtual”关键字。@B3ret幸运的是这不是一个问题,因为它们是纯虚拟函数,它们在vtable中仍然只有一个条目。只有当一个函数或虚拟函数有多个候选实现时,才会出现问题。感谢您添加此选项。
    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(); }
    };