12.5 isGreater函数
对于像int和double这样的基本类型,可以使用比较操作符比较值并判断大小。不过这些操作符(如<和>等等)不适用于用户定义类型。就像上一节,为了实现类似==操作符的功能,我们定义了equals函数,现在我们来写一个比较函数以实现类似>操作符的作用。 后面,我们会使用这个函数对一副牌进行排序。
有些集合是完全有序的,也就是说集合中的任意两个元素都可以比较大小。例如,整型数集合和浮点数集合就是完全有序的。 而有的集合是无序的,即不存在有意义的方法来比较集合中两个元素的大小。例如,水果的集合就是无序的,这也是我们无法比较苹果和句子的原因。另一个例子,bool类型也是无序的,我们并不能说true比false大。
扑克牌集合是部分有序的,也就是说我们有时可以对牌进行比较,而有时却不能。比如,我们知道梅花3比梅花2大,因为3比2大;方块3比梅花3大,因为方块比梅花大。但是,梅花3和方块2谁大呢?一个数值更大,而另一个花色更大。
为了让卡牌称为可比较的,我们需要决定大小和花色哪个更为重要。老实说,选择完全是随意的。 为了选择,我可以说花色更重要,因为新买的牌是有序的,所有的梅花放在一起,而且都在方块的前面,诸如此类。
根据这个决策,我们就可以编写isGreater函数了。再一次,参数(两张牌)和返回类型(布尔值)是显而易见的,我们还是要在将isGreater设计为成员函数或非成员函数之间做出选择。这一次,参数不是对称的了。我们到底想知道“A是否大于B”或“B是否大于A”是很重要的。所以我认为把isGreater设计为成员函数更有意义。
bool Card::isGreater (const Card& c2) const
{
// 首先检查花色
if (suit > c2.suit) return true;
if (suit < c2.suit) return false;
// 如果花色相等,检查大小
if (rank > c2.rank) return true;
if (rank < c2.rank) return false;
// 如果大小也相同,返回false
return false;
}
调用时,根据两个可能的问题,语法也很明显:
Card card1 (2, 11);
Card card2 (1, 11);
if (card1.isGreater (card2)) {
card1.print ();
cout << "is greater than" << endl;
card2.print ();
}
你几乎可以用英语读出来:”If card1 isGreater card2 ...“。程序的输出是:
Jack of Hearts
is greater than
Jack of Diamonds
根据isGreater函数,牌A小于牌2。 作为联系,请修改isGreater函数,使A比K大,因为大多数纸牌游戏中都是这样的。