类Class(一):class

 

 

类(classes)是数据结构(structures)的一个扩展概念。类(class)是一种将数据和函数组织在同一个结构里的逻辑方法。其功能与C语言中的 struct 类似,不同之处是 class 可以包含函数, struct 只能包含数据元素定义类的关键字为 class 或关键字 struct 。

 

    class class_name{

      access_specifier_1:

      member_1;

      access_specifier_2:

      member_2;

      ...

    }object_names;

 

其中 class_name 是类的名称 (用户自定义的类型) ,而可选项object_names 是这个类的一个或多个对象(object)标识。Class 的声明体中包含成员 members,成员可以是数据或函数定义,同时也可以包括访问说明符(access specifier)或允许范围标志(permission labels),范围标志可以是以下三个关键字中任意一个:private:, public: 或 protected:。它们分别代表以下含义:

 

  • privateclass private 成员,只有同一个 class 的其他成员或该 class 的“friendclass可以访问这些成员。
  • protectedclass protected成员,只有同一个class 的其他成员,或该 class 的“friendclass,或该 class 的子类(derived classes) 可以访问这些成员。
  • public :class 的 public 成员,该类的对象(object)无论在哪都可以访问这些成员。

 

如果我们在定义一个 class 成员的时候没有声明其允许范围,这些成员将被默认private 范围。例如:

 

    class Rectangle{

      int width, height;

      public :

      void set_values(int, int);

      int area(void);

    }rect;

 

上面例子定义了一个class Rectangle 和该 class 类型的对象变量 rect 。这个class 有4个成员:两个整型变量 (width 和 height) ,在private 部分 (因为private 是默认的允许范围);以及两个函数, 在 public 部分:set_values() 和 area(),这里只包含了函数的原型(prototype)。

注意 class名称与对象(object)名称的不同:在上面的例子中,Rectangle 是class 名称 (即用户定义的类型名称),而rect 是一个 Rectangle 类型的对象名称。它们的区别就像下面例子中类型名 int和 变量名a 的区别一样:

 

    int a;

 

int 是class名称 (类型名) ,而a 是对象名 object name (变量)。

在程序中,我们可以通过使用在对象名和成员名称之间加一点.”(dot) (同使用C structs一样),来引用对象rect 的任何public成员,就像它们只是一般的函数或变量。例如:

 

    rect.set_values(2,3);

    myarea = rect.area();

 

但我们不能够引用 width 或 height ,因为它们是该 class 的 private 成员,它们只能够在该 class 的其它成员中被引用。下面是关于class Rectangle的例子:

 

#include <iostream>
using namespace std;

class Rectangle {
    int width, height;
  public:
    void set_values (int, int);
    int area() {return width*height;}
};

void Rectangle::set_values (int x, int y) {
  width = x;
  height = y;
}

int main () {
  Rectangle rect;
  rect.set_values (3,4);
  cout << "area: " << rect.area();
  return 0;
}
area: 12

 

上面代码中新的东西是在定义函数set_values()时使用的范围操作符(双冒号:: )。它是用来在一个 class 之外定义该 class 的成员。注意,我们在Rectangle class 内部已经定义了函数 area() 的具体操作,因为这个函数非常简单。而对函数 set_values() ,在 class 内部只是定义了它的原型(prototype),而其实现是在 class 之外定义的。这种在 class 之外定义其成员的情况必须使用范围操作符::

范围操作符 (::) 声明了被定义的成员所属的 class 名称,并赋予被定义成员适当的范围属性,这些范围属性与在 class 内部定义成员的属性是一样的。例如,在上面的例子中,我们在函数 set_values() 中引用了private 变量 width 和 height,这些变量只有在 class 内部和它的成员中才是可见的。

在 class 内部直接定义完整的函数,和只定义函数的原型而把具体实现放在class外部的唯一区别在于,在第一种情况中,编译器(compiler) 会自动将函数作为inline(参考inline的小知识) 考虑,而在第二种情况下,函数只是一般的class成员函数。在行为上相同,但在编译器优化的可能性上不同。

我们把 width 和 height 定义为 private 成员 (记住,如果没有特殊声明,所有 class 的成员均默认为 private ),原因是我们已经定义了一个设置这些变量值的函数 (set_values()) ,这样一来,在程序的其它地方就没有办法直接访问它们。也许在一个这样简单的例子中,你无法看到这样保护两个变量有什么意义,但在比较复杂的程序中,这是非常重要的,因为它使得变量不会被意外修改 (主要指的是从object的角度来讲的意外)。

类 class 的一个最重要的属性是,它是一个类型(type),因此我们可以用它来定义多个不同对象(object)。例如,接着上面class Rectangle的例子,除了对象rect之外,我们还可以定义对象rectb :

 

#include <iostream>
using namespace std;

class Rectangle {
    int width, height;
  public:
    void set_values (int, int);
    int area () {return width*height;}
};

void Rectangle::set_values (int x, int y) {
  width = x;
  height = y;
}

int main () {
  Rectangle rect, rectb;
  rect.set_values (3,4);
  rectb.set_values (5,6);
  cout << "rect area: " << rect.area() << endl;
  cout << "rectb area: " << rectb.area() << endl;
  return 0;
}
rect area: 12
rectb area: 30 

 

注意: 调用函数 rect.area() 与调用 rectb.area()所得到的结果是不一样的。这是因为每一个 class Rectangle 的对象都拥有它自己的变量 width 和 height,以及它自己的函数set_values() 和 area()。

这是基于对象( object) 和 面向对象编程 (object-oriented programming)的概念的。这个概念中,数据和函数是对象(object)的属性(properties),而不是像以前在结构化编程 (structured programming) 中所认为的对象(object)是函数参数。我们在以后的内容里慢慢讨论面向对象的好处。

在这个具体的例子中,我们讨论的 class (object的类型)是 Rectangle,有两个实例(instance),或称对象(object):rect 和 rectb,每一个有它自己的成员变量和成员函数。



posted on 2014-03-27 16:14  guozqzzu  阅读(702)  评论(0编辑  收藏  举报