我正在尝试将公共基类的对象进行比较.在两种对象在类中不同的情况下,比较应该失败(例如,输出失败的字符串),或者对象特有的值不同.理想情况下,比较是以某种方式实现的,这样一个新的派生类也必须为其类的成员编写一个比较函数.这是一个代码示例:
#include <iostream> #include <string> #include <vector> class Vehicle { public: virtual std::string compareTo(Vehicle* v) = 0; }; class Bicycle : public Vehicle { public: Bicycle() { color_ = "red"; } std::string compareTo(Vehicle* v) { return "We're different vehicles."; } std::string compareTo(Bicycle* b) { return color_.compare(b->color_) ? "We're different bicycles." : "We're the same bicycle."; } private: std::string color_; }; class Car : public Vehicle { public: Car() { style_ = "sedan"; } std::string compareTo(Vehicle* v) { return "We're different vehicles."; } std::string compareTo(Car* c) { return style_.compare(c->style_) ? "We're different cars." : "We're the same car."; } private: std::string style_; }; int main() { Vehicle* compareFrom = new Bicycle(); std::vector<Vehicle*> compareTos; compareTos.push_back(new Bicycle()); compareTos.push_back(new Car()); std::vector<Vehicle*>::iterator it; for (it = compareTos.begin(); it != compareTos.end(); ++it) std::cout << compareFrom->compareTo(*it) << std::endl; return 0; }
目前,输出(你可以看到here)说“我们是不同的车辆”.我知道这是因为我使用抽象基础指针.问题是如何解决它!
我想要的输出是,自行车的输出是相同的,因为它们具有相同的颜色.自行车和汽车应该输出它们是不同的车辆.不同颜色的自行车和不同风格的汽车也应该输出它们是不同的.我觉得有必要使用很好的模式来解决这个问题,但是我会陷入动态投射或不安全的downcast问题.此外,我希望在同一个类的成员之间执行比较功能(所以自行车必须能够与其他自行车比较).
解决方法
你想要
Multiple Dispatch(即根据多个变量选择哪个函数可以动态调用,而不仅仅是’this’).这是因为您需要以某种方式检查类型,否则编译器将对类型进行静态分析,并选择要调用的函数(Vehicle中的虚拟函数).
没有办法. dynamic_cast是您的朋友,但由于性能(或其他原因),您可能希望滚动自己的RTTI系统. (维基百科文章显示一种方式..)
std::string Bicycle::compareTo(Vehicle* v) { if (Bicycle* b = dynamic_cast<Bicycle*>(v)) { return compareTo(b); } else { return "We're different vehicles."; } }
在Loki C++ library中有这种模式的实现,如果你有很多类型需要比较,这可能会有帮助.
C语言不支持多种调度,也不支持多数主流语言.有一个建议将其添加到C11,但是看到这个question和Bjarne’s paper.我认为它被拒绝,因为(已知的和未知的)动态链接的问题,C标准对此一无所知.