class或关键字struct来定义,语法如下:class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;
|
class_name是类的有效标识符,object_names是此类的对象的名称的可选列表。声明的体可以包含成员,这些成员可以是数据声明或函数声明,还可以包含可选的访问说明符。private、public或protected。这些说明符会修改它们后面的成员的访问权限。private成员只能从同一类的其他成员(或其“朋友”)内部访问。protected成员可以从同一类的其他成员(或其“朋友”)访问,也可以从其派生类的成员访问。public成员可以在任何可见对象的地方访问。class关键字声明的类的所有成员都具有私有访问权限。因此,在任何其他访问说明符之前声明的任何成员都自动具有私有访问权限。例如: |
|
Rectangle的类(即类型),以及该类的一个名为rect的对象(即变量)。该类包含四个成员:两个int类型的数据成员(成员width和成员height),具有私有访问权限(因为私有是默认的访问级别),以及两个具有公共访问权限的成员函数:函数set_values和area。目前我们只包含了它们的声明,而没有包含它们的定义。Rectangle是类名(即类型),而rect是Rectangle类型的对象。这与以下声明中的int和a的关系相同: |
|
int是类型名(类),a是变量名(对象)。Rectangle和rect之后,对象rect的任何公共成员都可以像访问普通函数或普通变量一样进行访问,只需在对象名和成员名之间插入一个点(.)即可。这与访问普通数据结构的成员的语法相同。例如: |
|
rect中唯一不能从类外部访问的成员是width和height,因为它们具有私有访问权限,只能在该类的其他成员内部引用。Rectangle类的完整示例: |
|
area: 12 |
::,两个冒号),该运算符在前面章节中与命名空间相关。此处用于在类外部定义类的成员函数set_values。area的定义已直接包含在类Rectangle的定义中,因为其极其简单。相反,set_values仅在类中用其原型声明,但其定义在类外部。在此外部定义中,使用作用域运算符(::)来指定正在定义的函数是Rectangle类的成员,而不是常规的非成员函数。::)指定了正在定义的成员所属的类,提供了与将此函数定义直接包含在类定义中完全相同的范围属性。例如,上例中的函数set_values可以访问变量width和height,它们是Rectangle类的私有成员,因此只能从该类的其他成员(例如这个函数)访问。width和height具有私有访问权限(请记住,如果没有指定其他内容,使用class关键字定义的类的所有成员都具有私有访问权限)。通过将它们声明为私有,不允许从类外部访问。这是有意义的,因为我们已经定义了一个成员函数来为对象中的这些成员设置值:成员函数set_values。因此,程序的其余部分不需要直接访问它们。也许在这个如此简单的例子中,很难看出限制对这些变量的访问有何用处,但在更大的项目中,防止值以意外的方式(从对象的角度来看是意外的)修改可能非常重要。Rectangle类的先前示例为例,我们可以除了对象rect之外,还可以声明对象rectb: |
|
rect area: 12 rectb area: 30 |
Rectangle,它有两个实例(即对象):rect和rectb。它们中的每一个都有自己的成员变量和成员函数。rect.area()的结果与调用rectb.area()的结果不同。这是因为Rectangle类的每个对象都有自己的变量width和height,因为它们(以某种方式)也有自己的函数成员set_value和area,这些函数作用于对象自己的成员变量。rect.area或rectb.area时没有传递任何参数。这些成员函数直接使用了它们各自对象rect和rectb的数据成员。set_values之前调用成员函数area会发生什么?结果不确定,因为成员width和height从未被赋值。void。Rectangle类可以通过实现构造函数来轻松改进: |
|
rect area: 12 rectb area: 30 |
Rectangle类没有成员函数set_values,而是有一个构造函数执行类似的操作:它使用传递给它的参数来初始化width和height的值。 |
|
void:构造函数从不返回值,它们只是初始化对象。 |
|
rect area: 12 rectb area: 25 |
Rectangle类的对象:rect和rectb。rect使用两个参数构造,如之前的示例所示。rectb调用了默认构造函数。请注意,rectb甚至没有用一对空括号构造——实际上,空括号不能用于调用默认构造函数。 |
|
rectc声明为函数,而不是对象声明:它将是一个不接受任何参数并返回Rectangle类型值的函数。class_name object_name = initialization_value; {})而不是圆括号(()):class_name object_name { value, value, value, ... } |
|
foo's circumference: 62.8319 |
|
|
initializer_list作为其类型的偏好。:)和类成员的初始化列表来完成的。例如,考虑一个具有以下声明的类: |
|
|
|
|
|
|
|
|
|
foo's volume: 6283.19 |
Cylinder类有一个成员对象,其类型是另一个类(base的类型是Circle)。由于Circle类的对象只能通过参数构造,因此Cylinder的构造函数需要调用base的构造函数,而唯一的方法是在成员初始化列表中进行。{})而不是圆括号(()): |
|
|
|
Rectangle类对象的指针。->)从指针直接访问对象成员。以下是一个包含一些可能组合的示例: |
|
*、&、.、->、[])。它们可以解释为:| 表达式 | 可以读作 |
|---|---|
*x | x指向的对象 |
&x | x的地址 |
x.y | 对象x的成员y |
x->y | 指向x的对象成员y |
(*x).y | 指向x的对象成员y(与上一行等效) |
x[0] | x指向的第一个对象 |
x[1] | x指向的第二个对象 |
x[n] | x指向的第(n+1)个对象 |
[]),而普通数据结构章节介绍了箭头运算符(->)。class定义,还可以使用关键字struct和union定义。struct通常用于声明普通数据结构,但也可以用于声明具有成员函数的类,语法与关键字class相同。两者之间的唯一区别是,使用关键字struct声明的类的成员默认具有public访问权限,而使用关键字class声明的类的成员默认具有private访问权限。在所有其他方面,在这方面这两个关键字是等效的。struct和class定义的类不同,因为联合一次只能存储一个数据成员,但尽管如此,它们也是类,因此也可以包含成员函数。联合类中的默认访问权限是public。其他数据类型 | 目录 | 类 (II) |