句柄类

C++的访问控制允许将实现部分和接口部分分开,但实现部分的隐藏是不完全的。编译器仍然必须知道一个对象的所有部分的声明,以便正确的创建和管理它。所以使用这个库的程序员仍然可以从头文件中看到这个类的私有函数或私有成员变量的声明,这种情况有时候也是有隐患的,有些程序员可能会不顾一切的用指针和类型转换来访问这些私有成员从而造成程序的崩溃或者算法被破译;还有一个坏处是,在程序的开发阶段,虽然那些共有接口不会经常的修改,但那些私有实现,接口会经常修改,成员变量会经常的添加或减少,难免会不断的修改头文件,从而造成包含这个头文件的所有文件被不断的重新编译。如果这个项目非常大,用于编译的时间过多可能妨碍项目的进度。
 
解决这个问题的技术是使用句柄类(handle class)或称为"Cheshire cat"。有关实现的任何东西都不出现在头文件中,只剩一个单指针。该指针指向一个结构,该结构的定义与其所有的成员函数的定义一同放到具体的实现文件中。这样,只要接口部分不改变,头文件就不需要变动。而实现部分可以按需要任意修改,我们只需要对实现文件进行重新编译,然后重新链接到项目中。
举个例子:
//userlib.h
#ifndef USERLIB_H
#define USERLIB_H
 
class UserLib
{
     struct Cheshire;   //只是声明
     Cheshire *smile;
 
public:
    void initialize();
    void cleanup();
    int read();
    void change(int);
};
#endif //USERLIB_H
 
//userlib.cpp
#include "userlib.h"
 
// 具体的实现,可以把所有的私有变量或私有函数放在这个结构(类)中
struct UserLib::Cheshire
{
    int i;
};
 
void UserLib::initialize()
{
    smile = new Cheshire;
    smile->i = 0;
}
 
void UserLib::cleanup()
{
    delete smile;
}
 
int UserLib::read()
{
    return smile->i;
}
 
void UserLib::change(int x)
{
    smile->i = x;
}
 
Cheshire是一个嵌套的结构,所以必须用作用域符号定义。在UserLib::initialize()中,为Cheshire结构分配存储空间,在UserLib::cleanup()中释放这些存储空间,这些存储空间被用来代替类的所有的private部分。当编译UserLib.cpp时,这个结构的定义被隐藏在目标文件中,没有人能看到它。如果改变Cheshire的组成,唯一要重新编译的是UserLib.cpp,因为头文件并没有改变。使用这个库客的程序员唯一能访问的就是公共的接口部分,并且能看到的也只有这些接口,所有的细节全都放在Cheshire结构中,隐秘性更加完善。
一个类的公共接口部分是使用这个类的程序员唯一能看到的。所以在分析设计阶段,保证接口的正确性更加重要。但这并不是说接口不能做修改。如果第一次没有正确的设计接口部分,可以再增加函数,这样就不需要删除那些已使用该类的程序代码来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值