C++ 中派生类的相等性测试
可能的重复:
重载运算符==的正确方法是什么类层次结构?
在 C++ 中,派生类如何以有意义的方式重写基类相等性测试?
例如,假设我有一个基类 A。类 B 和 C 派生自 A。现在给定两个指向两个 A 对象的指针,我可以测试它们是否相等(包括任何子类数据)吗?
class A {
public: int data;
};
class B : public A {
public: float more_data; bool something_else;
};
class C : public A {
public: double more_data;
};
A* one = new B;
A* two = new B;
A* three = new C;
//How can I test if one, two, or three are equal
//including any derived class data?
有干净的方法吗?我最好的选择是什么?
谢谢!
Possible Duplicate:
What’s the right way to overload operator== for a class hierarchy?
In C++, how can derived classes override the base class equality test in a meaningful way?
For example, say I have a base class A. Classes B and C derive from A. Now given two pointers to two A objects, can I test if they are equal (including any subclass data)?
class A {
public: int data;
};
class B : public A {
public: float more_data; bool something_else;
};
class C : public A {
public: double more_data;
};
A* one = new B;
A* two = new B;
A* three = new C;
//How can I test if one, two, or three are equal
//including any derived class data?
Is there a clean way of doing it? What's my best bet?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我记得读过对 public-non-virtual/non-public-virtual 习语及其优点的简洁描述,但不记得在哪里。 这本维基百科有一个不错的描述。
以下是将其应用到 op== 的方法:
I remember reading a succinct description of the public-non-virtual/non-public-virtual idiom and its advantages, but not where. This wikibook has an okay description.
Here is how you apply it to op==:
不同的派生类可以创建相同的对象吗?
如果是这样: 双重调度 是一个选项:它确实需要在基类中重载,所以你将会有依赖关系
如果没有:解决方案是在operator==()中检查typeid,如果它们不同则返回false。否则,调用私有 equal() 函数,其中派生类可以执行 static_cast 并进行比较。
这避免了所有派生类中的类型检查
Can different derived classes make equal objects?
If so: double dispatch is an option: it does need overloading in the base class, so you will have dependencies
If not: a solution is in the operator==() to check the typeid and return false if they're different. Otherwise call a private equal() function in which the derived class can do a static_cast and compare.
This avoids type-checks in all derived classes
实现此目的的一种方法是使用虚拟运算符==,它将基类对象作为参数,以便它可以与不同的派生对象一起正常工作。但是,您需要使该函数成为纯虚函数,以便强制所有派生对象实现它。所以你将无法实例化基类。例如:
One way of doing this is to use the
virtual operator==
which takes the base class object as the parameter so that it works properly with different derived objects. However, you need to make this function pure virtual so as to force all the derived objects to implement it. So you will not be able instantiate the base class. For example:如果您不关心类型 A 与类型 B 或 B 与 C 等的比较,那么您可以简单地为每个类实现一个重载的相等运算符:
但这很危险,因为如果您从 B 派生一个新类 D 或C,你将会遇到问题。
否则,您需要使用大量的dynamic_cast<>-ing来实现一些比较器才能真正做到正确。或者,您可以实现一个函数来为每个对象创建哈希码并利用它,例如,
如果您以某种方式将对象的类型合并到哈希码中(上面未显示),那么您也可以省去上面愚蠢的 typeid() 比较。
If you don't care about comparisons of type A to type B, or B to C, etc. then you can simply implement an overloaded equality operator for each class:
That's dangerous though, because if you derive a new class D from B or C, you're going to have problems.
Otherwise you need to implement some comparators with a lot of dynamic_cast<>-ing to really do it right. Alternatively you could implement a function to create a hash code for each object and leverage that, e.g.
If you incorporate the object's type into the hash code in some fashion (not shown above) then you can also dispense with the silly typeid() comparisons above.
如果您不介意基类引用子类,那么可以双重调度:
不需要dynamic_casts。
If you don't mind the base class referring to the sub-classes then double-dispatch:
Does it without requiring dynamic_casts.