我会这样实现它:
class A{
int a;
public:
virtual int Compare(A *other);
};
class B : A{
int b;
public:
/*override*/ int Compare(A *other);
};
int A::Compare(A *other){
if(!other)
return 1; /* let's just say that non-null > null */
if(a > other->a)
return 1;
if(a < other->a)
return -1;
return 0;
}
int B::Compare(A *other){
int cmp = A::Compare(other);
if(cmp)
return cmp;
B *b_other = dynamic_cast<B*>(other);
if(!b_other)
throw "Must be a B object";
if(b > b_other->b)
return 1;
if(b < b_other->b)
return -1;
return 0;
}
这与 .NET 中的模式非常相似IComparable
,效果很好。
编辑:
对上述内容的一个警告是a.Compare(b)
(where a
is a and b
is a B) 可能会返回相等,并且永远不会抛出异常,而b.Compare(a)
会。有时这是你想要的,有时不是。如果不是,那么您可能不希望您的Compare
函数是虚拟的,或者您希望比较type_info
基Compare
函数中的 s,如下所示:
int A::Compare(A *other){
if(!other)
return 1; /* let's just say that non-null > null */
if(typeid(this) != typeid(other))
throw "Must be the same type";
if(a > other->a)
return 1;
if(a < other->a)
return -1;
return 0;
}
请注意,派生类的Compare
函数不需要更改,因为它们应该调用基类的Compare
,type_info
比较将在其中进行。但是,您可以dynamic_cast
将覆盖Compare
函数中的 替换为static_cast
。