第6章 类和对象 7 ?; N) {6 j" l6 x: K
* c% C7 d4 S0 ^# s 6.1 类的定义
# a( k8 m2 R0 _& z6 N- L, s) R/ d3 g 1类的定义 6 {+ L/ ^ c+ _0 O( V) o
类的定义可以分为两部分:说明部分和实现部分。说明部分说明类中包含的数据成员和成员函数,实现部分是对成员函数的定义。类定义的一般格式如下: ! ~5 a8 g1 Z" o% J5 I/ K, v
//类的说明部分 ) g M4 x( ]& \9 u8 a: a5 ~
class<类名> / x5 p7 X0 T! U7 M. b0 u& Y
{ ) K/ I* K; v- ^! Z
public: - o: j" _& y0 v8 X0 N
<成员函数或数据成员的说明> //公有成员,外部接口
3 C E4 C7 I+ x3 o protected: * ^/ j% U: i: I( c. F# |" j5 r
<数据成员或成员函数的说明> //保护成员 7 S- ^) P, W0 Y, g5 c% L
private:
/ p* k" {) u I4 \! J( Q% z <数据成员或成员函数的说明> //私有成员
+ J0 k1 Z9 x7 N$ Y$ F+ _, b" w8 I }; 0 }6 b! R0 N# o e% M
//类的实现部分 7 L0 ?1 U8 ~! D: i9 c6 M6 N9 ]$ F7 C
<各个成员函数的实现>
( S( t; V3 n: z, }9 ]7 U 其中,class是声明类的关键字;<类名>是要声明的类的名字,必须符合标识符定义规则;花括号表示类的声明范围,说明该类的成员,其后的分号表示类声明结束。类的成员包括数据成员和成员函数,分别描述类所表达的问题的属性和行为。关键字public、private和protected称为访问权限修饰符,它们限制了类成员的访问控制范围。 + k7 q. U2 \' g' |$ h
各个成员函数的实现即可以在类体内定义,也可以在类体外定义。如果一个成员函数在类体内进行了定义,它将不出现在类的实现部分;如果所有的成员函数都在类体内进行了定义,则可以省略类的实现部分。在类体内定义的成员函数都是内联函数。
) }" s ]6 Q) k% Y* m' M- N7 W& P 2类成员的访问控制 0 n1 i( n, h/ R. w, j
类中提供了3种访问控制权限:公有(public)、私有(private)和保护(protected)。其中,公有类型定义了类的外部接口,任何一个外部的访问都必须通过外部接口进行;私有类型的成员只允许本类的成员函数访问,来自类外部的任何访问都是非法的;保护类型介于公有类型和私有类型之间,在继承和派生时可以体现出其特点。 " O9 O @- B. q4 F' ]/ }4 X
3类的数据成员 y: k5 C* {( F1 u% o" C7 A% g# c
类中的数据成员描述类所表达的问题的属性。数据成员在类体中进行定义,其定义方式与一般变量相同,但对数据成员的访问要受到访问权限修饰符的控制。 4 L4 v5 Y3 D, ]) _: P
在定义类的数据成员时,要注意以下几个问题。
5 ]: d) w+ R3 A& v! O (1)类中的数据成员可以是任意类型,包括整型、浮点型、字符型、数组、指针和引用等,也可以是对象。但是要注意,只有另外一个类的对象,才可以作为该类的成员,即作为该类的成员对象而存在。自身类的对象是不可以作为自身类的成员存在的,但自身类的指针可以。
+ |) `$ a& f& \+ W (2)在类体中不允许对所定义的数据成员进行初始化。 L/ v! j. Z" E3 l- ^3 n
4类的成员函数 ! g% V2 e. N' ]' c+ N, {0 }/ h
类的成员函数描述类所表达的问题的行为。类中所有的成员函数都必须在类体内进行说明。但成员函数的定义既可以在类体内给出,也可以在类体外给出。
# S r, k8 E" ?8 g7 O, h 第一种方式是将成员函数直接定义在类的内部。 7 j' x" b; S) o, q7 y0 j2 A
第二种方式是在类声明中给出对成员函数的说明,而在类外部对成员函数进行定义(但成员函数仍然在类范围内)。这种在类外部定义的成员函数的一般格式是:
2 h5 P! L }" M; z <返回类型><类名>::<成员函数名>(<参数表>) 3 |9 I$ x$ t' {- k2 o; ^
{ ( N3 N, I$ d! }& r0 K( C
<函数体> # ^: ^6 s F$ q
} K% n1 Z! M1 M6 {- ?. f
在类体外定义成员函数时,要注意必须在成员函数名前加上类名和作用域运算符(::)。作用域运算符用来标识某个成员属于某个类。作用域运算符的使用格式如下: : d' I* V( M( T) F1 G. E
<类名>::<成员函数名>(<参数表>)
/ ^$ W+ M1 e4 t9 v) q 或
0 }4 l4 e9 x9 q3 X7 o <类名>::<数据成员名> $ ~! u# M0 G9 `- ^3 O9 \7 n
成员函数的两种定义方式之间是有差别的。如果一个成员函数的声明和定义都在类体内,那么这个成员函数就是内联函数。如果一个成员函数的声明在类体内,而定义在类体外,这时对该成员函数的调用是按一般函数进行的。如果要将定义在类体外的成员函数也作为内联函数处理,就必须在成员函数的定义前加上关键字“inline”,以此显式地说明该成员函数也是一个内联函数。
" }' i) x/ h$ H1 g6 ] 成员函数除了可以定义为内联函数以外,也可以进行重载,可以对其参数设置默认值。 |