13.5 Deck成员函数

优质
小牛编辑
135浏览
2023-12-01

有了Deck对象之后,把所有从属于Deck的函数放入其结构定义中也是情理之中的事了。看一下到目前为止我们定义的函数,很明显12.7节的printDeck函数可以作为候选加进来。下面将printDeck重写为成员函数:

void Deck::print () const {
  for (int i = 0; i < cards.length(); i++) {
    cards[i].print ();
  }
}

通常,引用当前对象不需要使用点记号。

其他几个函数,至于是否应将它们变为Card或Deck的成员函数,还是作为以Card或Deck变量为参数的非成员函数,并非显而易见的。比如上一章以一个Card变量和一个Deck变量为参数的find函数,将它变为Card或Deck类型的成员函数都是合理的。作为练习,请重写find函数,其参数为Card类型,使之成为Deck的成员函数。

将find改写为Card的成员函数需要一些小技巧,这是我写的版本:

int Card::find (const Deck& deck) const {
  for (int i = 0; i < deck.cards.length(); i++) {
    if (equals (deck.cards[i], *this)) return i;
  }
  return -1;
}

一个技巧是,必须使用this关键字来引用调用find函数的对象;再就是在C++中定义相互引用的结构也需要一点技巧,因为编译器正在读取第一个结构定义时还不知道第二个结构的定义。

一种解决方案是,在Card定义之前先声明Deck,以后再给出Deck的定义。

// 声明Deck结构,这里不定义declare that Deck is a structure, without defining it
struct Deck;

// 这样我们就可以在Card的定义中引用Deck
struct Card
{
  int suit, rank;
  Card ();
  Card (int s, int r);
  void print () const;
  bool isGreater (const Card& c2) const;
  int find (const Deck& deck) const;
};

// 后面给出Deck的定义
struct Deck {
  apvector<Card> cards;

  Deck ();
  Deck (int n);
  void print () const;
  int find (const Card& card) const;
};