我有一些基本类型的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 ==
}
Run Code Online (Sandbox Code Playgroud)
wol*_*ang 10
使用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;
}
Run Code Online (Sandbox Code Playgroud)
从性能的角度来看:
typeid往往是便宜的,简单地查找存储在虚拟表中的指针.您可以廉价地比较动态类型的相等性.
然后,一旦您知道自己拥有合适的类型,就可以放心使用static_cast.
dynamic_cast因为"与虚拟函数调用相比"而言速度慢(就像"与java中的强制转换相比"一样慢),因为它还会分析类层次结构来处理继承(和多个继承,也).你不需要在这里处理.