C++虚继承问题:重写virtual function 'Polygon::area'存在歧义
解决C++虚继承中虚函数歧义的问题
嘿,这个问题是虚继承场景里很典型的陷阱,咱们来理清楚问题出在哪,以及怎么解决:
为什么会出现歧义?
你用virtual继承确实解决了基类Polygon多次实例化的问题(避免Square里有两个Polygon的副本),但这并没有解决另一个核心问题:Rectangle和Rombus都各自实现了Polygon的纯虚函数area()。当Square同时继承这两个类时,编译器不知道应该用哪个父类的area()来覆盖Polygon的虚函数——两个父类的实现都是合法的候选,这就导致了歧义报错。
简单说:虚继承只统一了基类的实例,但没统一中间类对虚函数的实现。
怎么解决?
你需要在Square类里显式重写area()函数,明确告诉编译器应该使用哪个父类的实现,或者提供一个全新的实现。这里有两种常见的做法:
方法1:调用其中一个父类的area实现
因为Square是正方形,Rectangle::area()和Rombus::area()的计算结果是一致的(都是边长×边长),所以你可以随便选一个调用:
class Square : public Rectangle, public Rombus { public: Square(double a) : Rectangle(a, a), Rombus(a, a) {} // 显式重写area,消除歧义 double area() override { return Rectangle::area(); // 或者 return Rombus::area(); 结果完全一致 } };
方法2:自己实现Square的area逻辑
如果你不想依赖父类的实现,也可以直接在Square里写自己的计算逻辑(不过需要先把父类的成员变量改成protected,让子类能访问):
// 先修改Rectangle和Rombus的成员为protected class Rectangle : public virtual Polygon { protected: double a, b; public: Rectangle(double a, double b) : a(a), b(b) {} double area() override { return a * b; } }; class Rombus : public virtual Polygon { protected: double a, h; public: Rombus(double a, double h) : a(a), h(h) {} double area() override { return a * h; } }; class Square : public Rectangle, public Rombus { public: Square(double a) : Rectangle(a, a), Rombus(a, a) {} double area() override { // 直接用父类的成员计算正方形面积 return Rectangle::a * Rectangle::a; } };
完整修改后的代码示例
class Polygon { public: virtual double area() = 0; }; class Rectangle : public virtual Polygon { protected: double a, b; public: Rectangle(double a, double b) : a(a), b(b) {} double area() override { return a * b; } }; class Rombus : public virtual Polygon { protected: double a, h; public: Rombus(double a, double h) : a(a), h(h) {} double area() override { return a * h; } }; class Square : public Rectangle, public Rombus { public: Square(double a) : Rectangle(a, a), Rombus(a, a) {} // 显式重写消除歧义 double area() override { return Rectangle::area(); } };
内容的提问来源于stack exchange,提问作者user3057544
相关产品推荐
相关产品推荐

