欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

类Class(一):class

程序员文章站 2022-07-16 22:49:38
...

 

 

类(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,每一个有它自己的成员变量和成员函数。