作者:rick1126
email: rickzhang@sina.com
日期:2001-7-19 6:51:34
第3章 隐藏实现
3.0 章节重点
讨论struct中的边界问题
3.1 设置限制
【关系的重要性】
. 任何关系之中, 存在一个双方遵循的边界是很重要的
. 产品库和使用者之间就建立了一种关系, 因此有必要出于商业或者其他目的在开发商和用户之间确定一个边界, 隐藏一些什么
【C语言中的struct】
. 和其他数据结构一样, 没有任何规则, 用户可以在struct中做任何事情, 没有一种机制去强制用户执行某些操作
. 比如一些必要的初始化和现场维护操作
【控制对于结构成员的处理的必要性】
. 让用户避开一些不需要的工具, 而这些工具涉及一些必须的内部处理不想让用户知道, 或者不必让用户显式的调用
. 让设计者可以改变内部实现而不用担心对于用户的影响
〖个人理解〗
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3.2 C++ 的存取控制
【struct的存取类型控制】
. public 成员就是一般的struct成员
. private 成员只能被类型创建者和内部成员函数使用
. protected 成员除了private具备类似特点还能和public一样被继承下去作为派生类的成员
〖个人理解〗
不同的存取类型实现了真正的数据封装, 以往的函数库恰恰类似现在的struct, 你可以决定那些是接口函数或者变量. 可以说函数库实现了部分意义上的封装, 但是没有类的层次和关系以及可扩展性. 不过你可以修改库的内部实现, 前提是维持接口稳定, 由此可见"边界"是多么重要, 任何teamwork都是如此, 不管你使用的是DLL, 类, COM都要具备一个接口的稳定性.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3.3 友元机制
【友元】
. 允许不属于当前结构的一个成员函数采取结构的数据
. 友元必须在结构内声明, 因为编译器必须能读取这个结构的声明以理解这个数据类型的大小, 行为等方面的规则; 该规则在任何关系都很只要
. "面子"是别人给的, 因此一个元素要成为结构的友元必须实现声明自己, 然后在结构被赋予友元资格
. 鉴于C++任何元素在被使用以前都必须被声明, 承袭上面一点, 即现有"友元"针对的元素, 再有赋予"友元"资格的结构, 但是友元元素操作的对象又是结构, 但是"授权"操作在友元元素的声明之后 -- 因此结构需要先进行一个"标记"声明, 该声明仅仅声明一个结构名称而已, 其后在"授权"操作的时候在进行详细的结构成员声明, 由此可见这是C++的一种安全措施, 保证数据的一致性, 减少了错误发生.
【友元的类型】
. 全局函数作为友元
. 另一个结构成员函数作为友元, 函数的存取类型不限
. 整个结构作为友元
. 结构被作为参数显式的传递给友元元素
【嵌套友元】
. 嵌套在结构内部的结构不会自动获得采取容器结构的私有成员的存取权限, 必须首先声明该嵌套结构, 然后赋予友元资格
. 注意上面嵌套结构的声明和授权的先后次序, 否则编译器不把它作为成员
. 这是一个不纯的C++机制, 为那些需要访问私有成员的元素打开了一扇窗
//容器结构
struct holder{
private:
int a[10];
public:
void initialize( );
//嵌套结构的声明
struct pointer{
pirvate:
holder* h; //这里因为容器结构已经声明, 即使不完整, 至少编译器已经知道它是什么了
int* p;
public:
void initialize( holder* H );
void next( );
void previous( );
void top( );
void end( );
int read( );
void set( int i );
//你也可以赋予容器结构访问你的私有成员的权利
friend holder::initialize( );
};
//容器结构赋予嵌套结构的友元资格
friend holder::pointer;
};
〖个人理解〗
"友元"容许那些外部元素或者内部元素访问指定结构的私有成员. 这其实体现了一种思维方式或者OPP的存取类型的准则, 对于private类型而言, 其保护不会因为元素的关系而改变, 不管是作为容器元素还是嵌套元素, 都不能默认地获得访问对应的嵌套/容器元素的私有成员, 除非拥有"友元"资格. 而且一旦获得"友元"资格, 所有私有类型对于它而言就是public.
其实说一些题外话, 这使得我想起东西方文化的差异, 就是"私有"的问题, 个人隐私应该是神圣不可侵犯的, 可是在东方, 人们总是有意无意的违反和放弃这一权利.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3.3 对象布局
【对象布局】
. 对象布局其实就是结构在内存之中的布局
. 一般按照存取块为单位是的内部的成员相邻分配内存
. 每一个存取块不一定需要顺序出现, 某些机器或者操作系统可以将private, protected块置于特定的内存区域
【运行时结构的对象布局】
. 存取信息在编译时就消失了, 在允许期间对象变成了一种和其他语言的编译产物一样的存储区域, 本质上已经不能防止设计时的规则的被破坏.
〖个人理解〗
这里的关键就是"设计时"和"运行时", 设计时你面对的是程序, 运行时不是你而是主机面对的就是存储和指令而已, 不管程序使用何种语言开发, 都没有意义, 因此存取控制仅仅是语言级别而不是操作系统级别, 尽管你可以设计这样一种操作系统.