如何在C++中制作可比类
How to make Comparable Class in C++
我想用C++做一个接口。如何在运算符重载语句中获取 op2.radius 值?我希望可比类可以用于其他类,例如矩形、线条等。
#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;
}
您需要进行向下投射,没有通用的方法来获取半径。
如果您确定传递给它的唯一对象是 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;
}
}
我们可以利用奇怪的重复模板模式 (CRTP) 将我们的派生类传递到 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}
}
(演示)
最重要的是,请注意Circle
类中operator<
和operator>
的专业化:
bool operator< (Circle const& other) const { return this->radius < other.radius; }
bool operator> (Circle const& other) const { return this->radius > other.radius; }
它们直接采用另一个Circle
作为参数。
您可以像使用 operator==
定义一个Equatable
抽象类。如果您的派生类(例如圆、数字、日期)可以同时比较排序和相等,则可以使用多重继承来继承Comparable
和Equatable
。
给读者的练习:实现(接口)所有6个关系运算符(<
,>
,==
,!=
,<=
,>=
Circle
),比较其半径。可能的解决方案在这里:演示。
我们不会在C++中制作像Comparable
这样的类。C++不是Java;它有自己的成语。您在标准库中看不到任何类似于Comparable
的东西,这强烈暗示您试图朝着错误的方向前进。
在你的特定情况下,不清楚bigger
应该做什么。你想比较圆形和三角形吗?如果没有,则没有圆形和三角形都属于Comparable
接口。如果是,如何?按地区?(如果是这样,那么你可以有一个virtual double area()
和一个调用它的非虚拟bool bigger()
)。圆圈和球体呢?你可以比较两个圆,或者两个球体,但是将一个圆和一个球体进行比较并没有多大意义。
同时拥有Circle::bigger
和Sphere::bigger
并没有错,但它们不能同时覆盖某个假设的公共基类或接口中的同一虚函数,即使你可以以某种方式为该函数发明一个工作签名。
- 没有找到相关文章