尝试使用虚拟继承解决钻石问题

Diamond issue when trying to resolve it using virtual inheritance

本文关键字:解决 钻石 问题 继承 虚拟      更新时间:2023-10-16

我是C++的新手,在解决钻石问题时我很差劲:这里的代码:

#include <iostream>
using namespace std;
// Base class
class Base 
{
   public:
      virtual void getArea()
      { 
         cout << "Called by Basen"; 
      }
};
// Derived class
class Rectangle: public virtual Base
{
   public:
      void getArea()
      { 
         cout << "Called by Rectanglen";
      }
};
// Derived class
class Square: public virtual Base
{
   public:
      void getArea()
      { 
         cout << "Called by Squaren";
      }
};
// Derived class
class Triangle: public Rectangle, Square
{
   public:
      void blabla(){}
};
int main(void)
{
    Triangle Tri;
    Tri.getArea();
    return 0;
}

我得到g++错误:

main.cpp:36:7: error: no unique final overrider for ‘virtual void Base::getArea()’ in ‘Triangle’
 class Triangle: public Rectangle, Square
       ^
main.cpp: In function ‘int main()’:
main.cpp:45:6: error: request for member ‘getArea’ is ambiguous
  Tri.getArea();
      ^
main.cpp:29:12: note: candidates are: virtual void Square::getArea()
       void getArea()
            ^
main.cpp:19:12: note:                 virtual void Rectangle::getArea()
       void getArea()

我在网上发现虚拟继承解决了这个问题,那么我的错误是什么呢。

提前感谢

作为编译器思考:应该调用什么方法?

你有一个三角形,既是正方形又是矩形,你问的是面积。您的三角形应该选择使用Rectangle.getArea()还是Square.getArea()

编译器无法知道。这里的解决方案是覆盖getArea()方法,例如:

class Triangle: public Rectangle, Square
{
   public:
      void blabla(){}
      void getArea()
      { 
         Square::getArea; //I'm a square
         Rectange::getArea; //I'm a rectangle
      }
};

即使没有基类,这个问题也会被触发。使用钻石继承的一个例子如下:

class Base
{
   protected:
      int x;
};

class Derived1: virtual public Base
{
   //some stuff
};

class Derived2: virtual public Base
{
   //some stuff
};

class Join: public Derived1, public Derived2
{
   int getX(){
     return x;
   }
};

在这里,使用虚拟继承允许我们在Join实例中只有基类的一个实例,而不是2个没有并且应该选择x的错误。

您的问题是,在相同的继承级别上有两个不同的类,它们提供了虚拟方法的不同重写。编译器无法知道哪一个应该优先,因此您需要提供自己的重写并执行任何您想要的操作(同时调用其中一个函数,或者滚动您自己的实现)。