类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:。它们分别代表以下含义:
- private :class 的 private 成员,只有同一个 class 的其他成员或该 class 的“friend” class可以访问这些成员。
- protected :class 的protected成员,只有同一个class 的其他成员,或该 class 的“friend” class,或该 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的例子:
|
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 :
|
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,每一个有它自己的成员变量和成员函数。