2013年(41)
分类: C/C++
2013-03-14 09:28:10
面向对象编程(OOP)有三个特性:封装、继承和多态性。Smalltalk、C++、Java、C#等面向对象语言在语言层次上支持OOP,而OOP并不是为特殊语言而使用的,用C和汇编也可以实现OOP的思想。
以下用C实现了OOP的三个特性之一:封装性,也即访问权限。
1. public访问权限(全局权限)---全局可见
关键:只要包含头,该头中声明的成员(属性、方法和宏)就是全局可见的。
如下图,A.h中的声明了v1和f1(), A.c中实现了方法f1(), App.c因为包含了A.h, 所以,在App.c中,v1和f1()都是可见的。
图1.public成员定义
2.protected访问权限(保护权限)---包内可见,包外继承中也可见
只在继承中可以使用的成员,在C中很难实现这种权限。一般用宏定义为public的形式,但在使用中要注意,只让这个成员在继承的类实例中使用(关于C的继承性在其它博文中)。
3.friendly访问权限(包内权限)---只在包内可见,包外不可见
概念:包含其它头的头我们叫它父头,如module1_pkg.h;而被包含的头我们叫它子头,如module1.h。
关键:(1)用多级包含的头文件,形成不同的包内包外访问权限,则父头的声明的成员为friendly访问权限。
(2)包内所有定义.c文件时都使用父头,而在包外使用子头,则父头中声明的成员(属性、方法和宏)在包内可见,而包外不同见。
module1目录就是一个包,其中有一个包头文件module1_pkg.h, 和所有.c文件。包头文件module1_pkg.h包含头文件module1.h,在包头module1_pkg.h是声明的成员---也就是friendly成员。
本包中所有.c文件使用包头module1.pkg.h,而其它包中的所有.c实现文件使用module1.h,则module1_pkg.h中声明的成员在module1包内可见,而在module2包中不可见,如图3.1。
也可以把成员定义在一个.c文件中,再用extern引用提升到module1_pkg.h中,则该成员在包含module1_pkg.h的其它.c文件中可见,而在包含module1.h的其它.c文件中不可见,如图3.2。
图3.1 直接定义的friendly变量和方法 图3.2 使用extern的friendly变量和方法
4. private访问权限(私有权限)---只在本.c文件内可见,其它位置不可见
关键:只在.c文件定义的成员(属性和方法),只能在本.c文件中可见,一般前边加一个static修饰(不加也一样),但为了与用extern修饰而被提升的成员进行区别,所以private成员前加static, 而被提升的成员不加static。
如下图,v2,f2是在A.c中声明和实现的,它们只能A.c中可见,在App.c中不可见。
图4. private成员定义
关键:extern修饰符并不是声明一个成员(属性和方法),只是个引用,并可以提升成员的访问权限。若采用分层的头结构,可以用extern提升成员为包内可见或全局可见。
一般把逻辑上相关的成员声明放在相近的位置,如放在A.c文件中,当要提升成员的访问权限时,可以在.h头中用extern来提升成员的访问权限。
用extern可以把private成员变成public成员;有时只是说明本文件中会用到某个成员(其它文件中已经声明的)而引用一下。
图5.extern的作用