双重继承:

时间:2012-08-27 17:31:37

标签: c++ inheritance multiple-inheritance

我的问题与以下结构有关: enter image description here

抽象级别仅用于提供“真实”类(D1和D2)的成员函数。由于需要高度优化,因此没有虚拟性(抽象级别的析构函数受到保护)。在下列情况下,带有B0-C1-C2-D1的部件是否完全正常:

  1. B0,C1和C2的成员函数有不同的名称吗?

  2. C1和C2有一个同名的功能(例如myFunction)?

  3. C1和C2和D1有一个同名的功能(例如myFunction)?

  4. B0和C2的功能名称相同但不是C1(例如myFunction)?

  5. 在每种情况下,D1将调用哪个版本的函数?

    编辑:一段快速的代码来说明:

    template<class CRTP> class A0
    {
        public:
            void myfunction1();
        protected:
            ~A0();
            double mymember;
    };
    
    template<class CRTP> class B0 : public A0<CRTP>
    {
        public:
            void myfunction2();
        protected:
            ~B0();
    };
    
    template<class CRTP> class C1 : public B0<CRTP>
    {
        public:
            void myfunction3();
        protected:
            ~C1();
    };
    
    template<class CRTP> class C2 : public B0<CRTP>
    {
        public:
            void myfunction4();
        protected:
            ~C2();
    };
    
    class D1 : public C1<D1>, public C2<D1>
    {
        public:
            void myfunction5();
    };
    

2 个答案:

答案 0 :(得分:0)

“完美确定”有些主观,但所有情况都在语言中明确定义。

您可能会遇到D1diamond inheritance的问题。 如果合适,您可以使用virtual inheritanceC1C2从公共基础继承。这并不总是合适的,我们难以猜测。

1)

他们是使用不同方法的不同类,没有冲突。

2)

C1C2内没有问题,但D1会有问题。

3)

您将 D1中定义它。继承的myFunction调用将从外部隐藏(无法访问)。您可以在D1中调用它们,如下所示:

struct D1 {
  void myFunction() {
    C1::myFunction();
    C2::myFunction();
  }
}

使用CRTP这样做会很烦人。我建议在类定义中使用typedef来保留你的理智。

4)

C1将具有B0赋予它的任何功能。如果它们不可访问,那么如果引用它们将会出现编译器错误。

老实说,我建议不要使用这种设计。将所有东西分解成小的具体物体并组成它们。保持这不是一个项目,它将是一个职业。

答案 1 :(得分:0)

我不会说没关系,除非您在课堂上两次A0B0,但它们是不同的班级(B0<C1>B0<C2>) 。除非你做一些专业化,否则很可能是not what you want

对此的可能解决方案是something like this,它会删除多重继承:

template<class CRTP, class Base = B0<CRTP> > class C1 : public Base
{
    public:
        void myfunction3();
    protected:
        ~C1();
};

template<class CRTP, class Base = B0<CRTP> > class C2 : public Base
{
    public:
        void myfunction4();
    protected:
        ~C2();
};

class D1 : public C2<D1,C1<D1>>
{
    public:
        void myfunction5();
};

那么,如果你想在那里拥有那颗钻石,你可以在没有多个基类实例的情况下做到这一点吗?
不,因为 a)正如我所说的基类不同而且 b)在C ++中,虚拟继承仅适用于具有vtable的类。