我有一些指向 Shape 基本类型的指针。我想使用 == 运算符比较这些对象。如果对象具有不同的派生类型,== 运算符显然应该返回 false。如果它们属于相同的派生类型,那么应该比较派生类型的成员。
我读到过使用 C++ RTTI 是一种不好的做法,应该只在极少数和必要的情况下使用。据我所知,如果不使用 RTTI,这个问题通常无法解决。每个重载的 == 运算符都必须检查 typeid,如果它们相同,则执行 dynamic_cast 并比较成员。这似乎是一个普遍的需求。这个问题有某种成语吗?
#include <iostream>
using namespace std;
class Shape {
public:
Shape() {}
virtual ~Shape() {}
virtual void draw() = 0;
virtual bool operator == (const Shape &Other) const = 0;
};
class Circle : public Shape {
public:
Circle() {}
virtual ~Circle() {}
virtual void draw() { cout << "Circle"; }
virtual bool operator == (const Shape &Other) const {
// If Shape is a Circle then compare radii
}
private:
int radius;
};
class Rectangle : public Shape {
public:
Rectangle() {}
virtual ~Rectangle() {}
virtual void draw() { cout << "Rectangle"; }
virtual bool operator == (const Shape &Other) const {
// If Shape is a Rectangle then compare width and height
}
private:
int width;
int height;
};
int main() {
Circle circle;
Rectangle rectangle;
Shape *Shape1 = &circle;
Shape *Shape2 = &rectangle;
(*Shape1) == (*Shape2); // Calls Circle ==
(*Shape2) == (*Shape1); // Calls Rectangle ==
}
最佳答案
使用 RTTI。
使用 typeid
,但使用 static_cast
而不是 dynamic_cast
。
从设计的角度来看,我想说这正是 RTTI 的目的,任何替代解决方案都必然会更丑陋。
virtual bool operator == (const Shape &Other) const {
if(typeid(Other) == typeid(*this))
{
const Circle& other = static_cast<const Circle&>(Other);
// ...
}
else
return false;
}
从性能的角度:
typeid
往往是廉价的,一个存储在虚拟表中的指针的简单查找。您可以廉价地比较动态类型的相等性。
然后,一旦知道类型正确,就可以安全地使用 static_cast
。
dynamic_cast
以速度慢着称(也就是说,“与虚函数调用相比”慢,而不是“与 java 中的转换相比”),因为它也会分析类层次结构以处理继承(以及多重继承)。你不需要在这里处理。
关于c++ - 在没有 RTTI 的情况下比较 C++ 中的多态基类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11332075/