我想在C ++中创建一个接口。 如何在运算符重载语句中获取op2.radius值? 我希望Comparable Class可以用于其他如Rectangle,Line等。
#include <iostream>
using namespace std;
class Comparable {
public:
virtual bool operator > (Comparable& op2)=0;
//virtual bool operator < (Comparable& op2)=0;
//virtual bool operator == (Comparable& op2)=0;
};
class Circle : public Comparable {
int radius;
public:
Circle(int radius=1) { this->radius = radius; }
int getRadius() { return radius; }
bool operator > (Comparable& op2)
{
if (radius > op2.radius) // <-- here!
return true;
else
return false;
}
};
template <class T>
T bigger(T a, T b){
if (a > b) return a;
else
return b;
}
void main()
{
Circle waffle(10), pizza(20), y;
y = bigger(waffle, pizza);
cout << "the bigger one is " << y.getRadius() << endl;
}
答案 0 :(得分:3)
我们不会在C ++中创建类似Comparable
的类。 C ++不是Java;它有自己的成语。您在标准库中看不到任何类似Comparable
的内容,这是您尝试向错误方向移动的强烈暗示。
在您的特定情况下,不清楚bigger
应该做什么。你想比较圆和三角形吗?如果不是,则圆和三角形都不属于Comparable
接口。如果有,怎么样?按地区划分? (如果是这样,那么您可以使用virtual double area()
和非虚拟bool bigger()
来调用它。圆圈和球体怎么样?你可以比较两个圆圈或两个球体,但是将一个圆圈与一个球体进行比较只是没有多大意义。
同时拥有Circle::bigger
和Sphere::bigger
没有任何问题,但它们不能同时覆盖某个假设的公共基类或接口中的同一个虚函数,即使你能以某种方式发明一个该功能的工作签名。
答案 1 :(得分:2)
你需要做一个向下投射,没有通用的方法来获得半径。
如果你确定传递给它的唯一对象是Circle类型,那么静态转换就足够了。
如果不是这种情况,那么尝试使用dynamic_cast来检查它是否是Circle对象。如果失败则返回false。
注意:dynamic_cast会降低性能。
bool operator > (Comparable& op2)
{
Circle* foo = dynamic_cast<Circle*>(&op2);
if (foo && (radius > foo->getRadius()))
{
return true;
}
else
{
return false;
}
}
答案 2 :(得分:0)
我们可以利用curiously recurring template pattern将派生类传递到Comparable
类中。这样,就无需强制转换参数。
#include <iostream>
template<typename T>
class Comparable {
public:
virtual bool operator< (T const& other) const =0;
virtual bool operator> (T const& other) const =0;
};
class Circle : public Comparable<Circle> { // note Circle itself is passed as a template parameter
public:
Circle(int radius = 1) : radius(radius) {}
bool operator< (Circle const& other) const { return this->radius < other.radius; }
bool operator> (Circle const& other) const { return this->radius > other.radius; }
friend std::ostream& operator<< (std::ostream& os, Circle const& c) {
os << "Circle{.radius=" << c.radius << "}";
return os;
}
private:
int radius;
};
int main()
{
Circle c1{5};
Circle c2{7};
std::cout << std::boolalpha;
std::cout << (c1 < c2) << std::endl; // true
std::cout << std::max(c1, c2) << std::endl; // Circle{.radius=7}
}
(Demo)
bool operator< (Circle const& other) const { return this->radius < other.radius; } bool operator> (Circle const& other) const { return this->radius > other.radius; }
最重要的是,请注意operator<
类中operator>
和Circle
的专业化直接将另一个Circle
作为参数。
您可以使用Equatable
类似地定义operator==
抽象类。如果可以比较派生类(例如Circle)的排序和相等性,则可以使用多重继承来继承Comparable
和Equatable
。