C ++中的多继承观察者模式实现

时间:2014-07-12 10:43:05

标签: c++ multiple-inheritance final observers

这是我在C ++中半个观察者模式的简化实现。 它没有编译,我有三个问题:

  1. 我需要做什么才能编译呢?错误是:
  2.   

    错误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'

    1. “多重继承解决方案”我认为你使用得很好吗?我不希望IMyInterface继承AObservable,因为我希望IMyInterface的实现者能够自己实现IObservable,如果他们愿意的话。

    2. 有点无关,但正如我们所说的那样。我认为virtual void raiseChanged() finalvoid raiseChanged()更明确,以告诉实现者我不希望这被覆盖。除了性能影响之外,这样做有什么不利之处吗?

    3. 代码:

      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;
      }
      

2 个答案:

答案 0 :(得分:1)

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

    这不会触发虚拟继承的任何问题,即"The dreaded diamond-shaped inheritance",只要你避免自己好。

  2. 您不会通过声明函数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(); }
};