C++编程思想03.pdf
《C++编程思想03.pdf》由会员分享,可在线阅读,更多相关《C++编程思想03.pdf(14页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、下载下载第3章隐 藏 实 现一个典型的C语言库通常包含一个结构和一组运行于该结构之上的相关函数。前面我们已经看到C+是怎样处理那些在概念上和语法上相关联的函数的,那就是:把函数的声明放在一个s t r u c t内,改变这些函数的调用方法,在调用过程中不再把 s t r u c t的地址作为第一个参数传递,在程序中增加一个新的数据类型(这样就不必在 s t r u c t关键字前加一个t y p e d e f之类的声明了)。这样做带来很多方便有助于组织代码,使程序易于编写和阅读。然而,在使得 C+库比以前更容易的同时,存在一些其他问题,特别是在安全与控制方面。本章重点讨论 s t r u c
2、 t中的边界问题。3.1 设置限制在任何关系中,存在相关各方都遵从的边界是很重要的。当我们建立了一个库之后,我们就与该库的用户(也可以叫用户程序员)建立了一种关系,他是另外的程序员,但他需要用我们的库来编写一个应用程序或用我们的库来建立更大的库。在C语言中,s t r u c t同其他数据结构一样,没有任何规则,用户可以在 s t r u c t中做他们想做的任何事情,没有办法来强制任何特殊的行为。比如,即使我们已经看到了上一章中提到的i n i t i a l i z e()函数和c l e a n u p()函数的重要性,但用户有权决定是否调用它们(我们将在下一章看到更好的方法)。再比如,
3、我们可能不愿意让用户去直接处理 s t r u c t中的某些成员,但在C语言中没有任何方法可以阻止用户。一切都是暴露无遗的。需要控制对结构成员的存取有两个理由:一是让用户避开一些他们不需要使用的工具,这些工具对数据类型内部的处理来说是必须的,但对用户特定问题的接口来说却不是必须的。这实际上是为用户提供了方便,因为他们可以很容易地知道,对他们来说哪些是重要的,哪些是可以忽略的。二是设计者可以改变 s t r u c t的内部实现,而不必担心对用户程序员产生影响。在上一章s t a c k的例子中,我们想以大块的方式来分配存储空间,提高速度,而不是在每次增加成员时调用malloc()函数来重新分
4、配内存。如果这些库的接口部分与实现部分是清楚地分开的,并作了保护,那么我们只需要让用户重新连接一遍就可以了。3.2 C+的存取控制C+语言引进了三个新的关键字,用于在 s t r u c t中设置边界:p u b l i c、p r i v a t e和p r o t e c t e d。它们的使用和含义从字面上就能理解。这些存取指定符只在 s t r u c t声明中使用,它们可以改变在它们之后的所有声明的边界。使用存取指定符,后面必须跟上一个冒号。p u b l i c意味着在其后声明的所有成员对所有的人都可以存取。p u b l i c成员就如同一般的s t r u c t成员。比如,下
5、面的s t r u c t声明是相同的:p r i v a t e关键字则意味着,除了该类型的创建者和类的内部成员函数之外,任何人都不能存取这些成员。p r i v a t e在设计者与用户之间筑起了一道墙。如果有人试图存取一个私有成员,就会产生一个编译错误。在上面的例子中,我们可能想让 struct B中的部分数据成员隐藏起来,只有我们自己能存取它们:第3章 隐 藏 实 现43下载虽然f o o()函数可以访问B的所有成员,但一般的全局函数如 m a i n()却不能,当然其他s t r u c t中的成员函数同样也不能。只有那些在这个s t r u c t中明确声明了的函数才能访问这些私有
6、成员。对存取指定符的顺序没有特别的要求,它们可以不止一次出现,它们影响在它们之后和下一个存取指定符之前声明的所有成员。保护(protected)最后一种存取指定符是p r o t e c t e d。p r o t e c t e d与p r i v a t e基本相似,只有一点不同:继承的结构可以访问p r o t e c t e d成员,但不能访问p r i v a t e成员。但我们要到第1 3章才讨论继承。现在就把这两种指定符当成一样来看待,直到介绍了继承后再区分这两类指定符。3.3 友元如果程序员想允许不属于当前结构的一个成员函数存取结构中的数据,那该怎么办呢?他可以在s t r u
7、 c t内部声明这个函数为友元。注意,一个友元必须在一个 s t r u c t内声明,这一点很重要,因为他(和编译器)必须能读取这个结构的声明以理解这个数据类型的大小、行为等方面的规则。有一条规则在任何关系中都很重要,那就是“谁可以访问我的私有实现部分”。类控制着哪些代码可以存取它的成员。让程序员没有办法“破门而入”,他不能声明一个新类然后说“嘿,我是鲍勃的朋友”,不能指望这样就可以访问鲍勃的私有成员和保护成员。程序员可以把一个全局函数声明为友元类,也可以把另一个 s t r u c t中的成员函数甚至整个s t r u c t都声明为友元类,请看下面的例子:44C+编程思想下载struct
8、 Y有一个成员函数f(),它将修改X类型的对象。这里有一个难题,因为C+的编译器要求在引用任一变量之前必须声明,所以struct Y必须在它的成员Y:f(X*)被声明为struct X的一个友元之前声明,但Y:f(X*)要被声明,struct X又必须先声明。解决的办法是:注意到Y:f(X*)引用了一个X对象的地址。这一点很关键,因为编译器知道如何传递一个地址,这一地址大小是一定的,而不管被传递的对象类型大小。如果试图传递整个对象,编译器就必须知道 X的全部定义以确定它的大小以及如何传递它,这就使程序员无法声明一个类似于Y:g(X)的函数。通过传递X的地址,编译器允许程序员在声明Y:f(X*)
9、之前做一个不完全的类型指定。这一点是在struct X的声明时完成的,这儿仅仅是告诉编译器,有一个叫 X的s t r u c t,所以当它被引用时不会产生错误,只要程序员的引用不涉及名字以外的其他信息。这样,在struct X中,Y:f(X*)就可以成功地声明为一个友元函数,如果程序员在编译器获得对Y的全部指定信息之前声明它,就会产生一条错误,这种安全措施保证了数据的一致性,同时减少了错误的发生。再来看看其他两个友元函数,第一个声明将一个全局函数 g()作为一个友元,但g()在这之前并没有在全局范围内作过声明,这表明f r i e n d可以在声明函数的同时又将它作为s t r u c t的友
10、元。这种声明对整个s t r u c t同样有效:friend struct Z是一个不完全的类型说明,并把整个s t r u c t都当作一个友元。3.3.1 嵌套友元一个嵌套的s t r u c t并不能自动地获得存取私有成员的权限。要获得存取私有成员的权限,必须遵守特定的规则:首先声明一个嵌套的 s t r u c t,然后声明它是全局范围使用的一个友元。第3章 隐 藏 实 现45下载s t r u c t的声明必须与f r i e n d声明分开,否则编译器将不把它看作成员。请看下面的例子:46C+编程思想下载struct holder包含一个整型数组和一个 p o i n t e r
11、,我们可以通过p o i n t e r来存取这些整数。因为p o i n t e r与h o l d e r紧密相连,所以有必要将它作为s t r u c t中的一个成员。一旦p o i n t e r被定义,它就可以通过下面的声明来获得存取h o l d e r的私有成员的权限:friend holder:pointer;注意,这里s t r u c t关键字并不是必须的,因为编译器已经知道p o i n t e r是什么了。因为p o i n t e r是同h o l d e r分开的,所以程序员可以在main()块中定义它的多个实例,然后用它们来选择数组的不同部分。由于 p o i n
12、 t e r是C语言中指针的替代,因此程序员可以保证它总是安全地指向h o l d e r的内部。第3章 隐 藏 实 现47下载3.3.2 它是纯的吗这种类的定义提供了有关权限的信息,我们可以知道哪些函数可以改变类的私有部分。如果一个函数被声明为f r i e n d,就意味着它不是这个类的成员函数,但却可以修改类的私有成员,而且它必须被列在类的定义中,因此我们可以认为它是一个特权函数。C+不是完全的面向对象语言,它只是一个混合产品。f r i e n d关键字就是用来解决部分的突发问题。它也说明了这种语言是不纯的。毕竟 C+语言的设计是为了实用,而不是追求理想的抽象。3.4 对象布局第2章讲
13、述了为C编译器而写的一个s t r u c t,然后一字不动地用C+编译器进行编译。这里我们就来分析s t r u c t的布局,也就是,各自的变量放在内存的什么位置?如果C+编译器改变了C struct中的布局,在C语言代码中如果使用了s t r u c t中变量的位置信息的话,那么在C+中就会出错。当我们开始使用一个存取指定符时,我们就已经完全进入了 C+的世界,情况开始有所改变。在一个特定的“存取块”(被存取指定符限定的一组声明)内,这些变量在内存中肯定是相邻的,这和C语言中一样,然而这些“存取块”本身可以不按定义的顺序在对象中出现。虽然编译器通常都是按存取块出现的顺序给它们分配内存,但
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 编程 思想 03
限制150内