类的成员函数

来源:互联网 发布:ubuntu安装网页播放器 编辑:程序博客网 时间:2024/05/18 00:44

  class Sales_item {
  public:
  // operations on Sales_item objects
  double avg_price() const;
  bool same_isbn(const Sales_item &rhs) const
  { return isbn == rhs.isbn; }
  // private members as before
  private:
  std::string isbn;
  unsigned units_sold;
  double revenue;
  };



 

每个成员函数(除了在第 12.6 节介绍的 static 成员函数外)都有一个额外的、隐含的形参 this。在调用成员函数时,形参 this 初始化为调用函数的对象的地址。为了理解成员函数的调用,可考虑下面的语句:


  total.same_isbn(trans);

就如编译器这样重写这个函数调用:

  // pseudo-code illustration of how a call to a member function is translated
  Sales_item::same_isbn(&total, trans);

在这个调用中,函数 same_isbn 中的数据成员 isbn 属于对象 total。

现在,可以理解跟在 Sales_item 成员函数声明的形参表后面的 const 所起的作用了:const 改变了隐含的 this 形参的类型。在调用 total.same_isbn(trans) 时,隐含的 this 形参将是一个指向 total 对象的 const Sales_Item* 类型的指针。就像如下编写 same_isbn 的函数体一样:

  // pseudo-code illustration of how the implicit this pointer is used
  // This code is illegal: We may not explicitly define the this pointer ourselves
  // Note that this is a pointer to const because same_isbn is a const member
  bool Sales_item::same_isbn(const Sales_item *const this,
  const Sales_item &rhs) const
  { return (this->isbn == rhs.isbn); }

用这种方式使用 const 的函数称为常量成员函数。由于 this 是指向 const 对象的指针,const 成员函数不能修改调用该函数的对象。因此,函数 avg_price 和函数 same_isbn 只能读取而不能修改调用它们的对象的数据成员。


在成员函数中,不必显式地使用 this 指针来访问被调用函数所属对象的成员。对这个类的成员的任何没有前缀的引用,都被假定为通过指针 this 实现的引用:

  bool same_isbn(const Sales_item &rhs) const
  { return isbn == rhs.isbn; }

在这个函数中 isbn 的用法与 this->units_sold 或 this->revenue 的用法一样。


由于 this 指针是隐式定义的,因此不需要在函数的形参表中包含 this 指针,实际上,这样做也是非法的。但是,在函数体中可以显式地使用 this 指针。如下定义函数 same_isbn 尽管没有必要,但是却是合法的:

  bool same_isbn(const Sales_item &rhs) const
  { return this->isbn == rhs.isbn; }


在类的定义外面定义成员函数必须指明它们是类的成员:

  double Sales_item::avg_price() const
  {
  if (units_sold)
  return revenue/units_sold;
  else
  return 0;
  }


上述定义和其他函数一样:该函数返回类型为 double,在函数名后面的圆括号起了一个空的形参表。新的内容则包括跟在形参表后面的 const 和函数名的形式。函数名:

  Sales_item::avg_price

使用作用域操作符指明函数 avg_price 是在类 Sales_item 的作用域范围内定义的。

形参表后面的 const 则反映了在类 Sales_item 中声明成员函数的形式。在任何函数定义中,返回类型和形参表必须和函数声明(如果有的话)一致。对于成员函数,函数声明必须与其定义一致。如果函数被声明为 const 成员函数,那么函数定义时形参表后面也必须有 const。

现在可以完全理解第一行代码了:这行代码说明现在正在定义类 Sales_item 的函数 avg_price,而且这是一个 const 成员函数,这个函数没有(显式的)形参,返回 double 类型的值。

函数体更加容易理解:检查 units_sold 是否为 0,如果不为 0,返回 revenue 除以 units_sold 的结果;如果 units_sold 是 0,不能安全地进行除法运算——除以 0 是未定义的行为。此时程序返回 0,表示没有任何销售时平均售价为 0。根据异常错误处理策略,也可以抛出异常来代替刚才的处理。