代码之家  ›  专栏  ›  技术社区  ›  Nick

菱形子问题:分支中的非多重继承仍然需要类构造函数

  •  2
  • Nick  · 技术社区  · 14 年前

    当我试图用通常的方法“解决”常见的菱形问题时,出现了一个奇怪的问题—使用虚拟继承:

      A
     / \* both virtual
    B   C
     \ /
      D
    

      A
     / \* both virtual
    B   C
     \ / \
      D   E
    

    仍然需要手动调用E中构造函数的构造函数,即C不知道从E创建什么,即使没有多重继承也没有菱形A-C-E。

    class A                     
       {public: 
          A (int _N): N(_N) {};
          void show()
            {cout<<"A"<<N;} 
        protected:
          int N;
       }; 
    class B: public virtual A   
       { public: 
           B(int n): A(2*n) {};
           void show()
            { cout<<"B"<<N;} 
       }; 
    class C: public virtual A   
       { public: 
           C(int n): A(3*n) {};
           void show()
            { cout<<"C"<<N;} 
       }; 
    class D: public B,C 
       { public: 
           D(): B(1), C(2), A(3) {};
           void show()
            { cout<<"D"<<N;} 
       }; 
    
    class E: public virtual C
       { public:
           E(): C(1) {};
           void show()
            { cout<<"E"<<N;} 
       }; 
    
    int main()
      {D d;       // OK
       A *a = &d; 
       a->show(); 
    
       E e;        // NOT OK, no function A::A() to call in E::E()
       A *a2 = &e;
       a2->show();
       return 0;
      } 
    

    有没有可能在不从E调用A的构造函数的情况下解决这个问题?我需要C来正确地做它:-)。

    或者根本不想解决钻石问题:

    A   A
    |   |  no virtual at all
    B   C
     \ / \
      D   E
    

    using C::A
    

    在D的声明中,它仍然产生明确的基A的错误。

    2 回复  |  直到 14 年前
        1
  •  3
  •   James McNellis    14 年前

    有没有可能在不从E调用A的构造函数的情况下解决这个问题?我需要C来正确地做它:-)。

    最派生类的构造函数(在本例中, E

    建造商 C 无法调用的构造函数 A 不是最派生的类。虚拟基类已初始化 之前 任何直接基类,所以 E 必须通过初始化 在初始化之前 C .

        2
  •  3
  •   curiousguy    13 年前

    • 可以重写派生类中的虚函数;
    • 不能重写基类构造函数的虚拟基类的init列表。

    这意味着:

    • 但当涉及基类构造函数调用时,虚拟继承会影响每个派生类。
    推荐文章