Как спроектировать наследование классов - PullRequest
0 голосов
/ 27 мая 2020

Я предоставляю 3 класса интерфейса для других IA, IB, IC。, а затем мне нужно реализовать эти 3 класса интерфейса. Мой метод реализации следующий, но поведение a () в трех классах такое же, как я могу повторно использовать код。

class IA{
    virtual void a() = 0;
};

class IB : public IA{
    virtual void b() = 0;
};

class IC: public IA{
    virtual void c() = 0;
};


class A :public IA{
    void a(){}
};

class B :public IB{
    void a(){}
    void b(){}
};

class C :public IC{
    void a(){}
    void c(){}
};

1 Ответ

0 голосов
/ 27 мая 2020

Есть несколько способов:

  • Создание общих функций:

    void f() { /*..*/ }
    
    class A : public IA{
        void a() override { f(); }
    };
    
    class B : public IB{
        void a() override { f(); }
        void b() override { /**/ }
    };
    
    class C : public IC{
        void a() override { f(); }
        void c() override { /**/ }
    };
    
  • использовать виртуальное наследование

    class IB : public virtual IA{
        virtual void b() = 0;
    };
    
    class IC : public virtual IA{
        virtual void c() = 0;
    };
    
    
    class A : public virtual IA{
        void a() override { /*..*/ }
    };
    
    class B : public A, public IB{
        void b() override { /**/ }
    };
    
    class C : public A, public IC{
        void c() override { /**/ }
    };
    
  • Использовать шаблон / CRTP

    template </*typename Derived,*/ typename Base>
    struct AImpl : public Base
    {
        void a() override { /*..*/ }
    };
    
    class A : public AImpl</*A,*/ IA> {
    };
    
    class B : public AImpl</*B,*/ IB> {
        void b() override { /**/ }
    };
    
    class C : public AImpl</*C,*/ IC> {
        void c() override { /**/ }
    };
    
  • Использовать состав

    class A : public IA{
        void a() override { /**/ }
    };
    
    class B : public IB{
        void a() override { mA.a(); }
        void b() override { /**/ }
    private:
        A a;
    };
    
    class C : public IC{
        void a() override { mA.a(); }
        void c() override { /**/ }
    private:
        A a;
    };
    
...