隐藏实现

 为了让一个类或者函数能够访问某个类里面的私有成员,可以把这个类或函数作为某个类的友元。比如,这里

面把全局函数main作为某个类的友元函数:
#include <iostream>
using namespace std;

struct  Test
{
private:
 int  m_a;

 friend int main();
};

int main()
{
 Test test;
 test.m_a  = 90; // 直接访问私有成员 ok
 cout << test.m_a << endl;

 return 1;
}


为了搞清楚访问权限的问题,我觉得先要建立区间的概念。一个函数是一个区间,一个struct是一个区间,一

个class是一个区间。区间struct或class可以用private和protected来筑起一道墙,以防止别的区间对其区间

进行访问。如果特意为某个区间开放的话,可以把某区间作为自己区间的朋友(friend)即可。
这些墙,在程序编译的时候才起作用。当程序运行时,所有的对象都是一个个存储块,里面的数据没有任何的

private之类的限定,对它的读写都是可能的。
C++是一种实用的语言,我不应该追求完美的封装,应该大胆使用friend和public。


这样写法是没有问题:我是在vc6.0上进行的测试。
#include <iostream>
using namespace std;

struct  A;
struct  B
{
public:
 void  f( A );  // 如果编译器从上住下编译的话,它是不知道参数A的大小的,但编译却通过了
};

struct A
{
private:
 int m_a;

 friend void B::f( A );
};

void B::f( A a )
{
 a.m_a  = 90;
 cout << a.m_a << endl;
}


int main()
{
 A  a;
 B  b;
 b.f( a );  // ok

 return 1;
}

这种写法更是没有问题:
#include <iostream>
using namespace std;

struct  A;
struct  B
{
public:
 void  f( A* ); // 编译器不用知道A的定义就知道这里面的参数要占几个字节,因为它是指针变量
};

struct A
{
private:
 int m_a;

 friend void B::f( A* );
};

void B::f( A* a )
{
 a->m_a  = 90;
 cout << a->m_a << endl;
}


int main()
{
 A  a;
 B  b;
 b.f( &a );  // ok of course

 return 1;
}


句柄思想在生活和开发上经常有体现,它核心就是“以小带大”。在vs2005的类视图中,从一个类名可以看到

一系列的函数,从一个函数名可以看到若干行代码的集合。。。这些都是以小带大的思想的体现。
使用句柄有两个好处:一是可以隐藏使用到的具体数据类型,包括它的声明而不仅是它的实现,避免竞争对手

等“敌人”猜测出你在使用什么技术。二是在这个具体数据类型发生改变时,所有包括这个句柄类头文件的cpp

文件都不需要编译(因为这个句柄类头文件没有改变),而只需要编译这个具体数据类型所在的cpp文件并连接

所有目标文件即可。
下面给出不使用和使用句柄类的例子:
/// 不使用句柄类的情况:
// RealClass.h文件
#ifndef _HANDLE_H
#define _HANDLE_H

struct  RealClass  // 这个类的定义暴露在头文件中
{
 int  m_data;
};

#endif
以上没有使用句柄类,除了暴露之外,当RealClass类发生改变时,所有包含这个头文件的cpp文件都要重新编

译。


/// 使用句柄类的情况:
// handle.h文件
#ifndef _HANDLE_H
#define _HANDLE_H

class Handle  // 句柄类
{
private:
 struct  RealClass;  // 这个是实际的类,它的任何信息在这个文件中都看不到
 RealClass * m_pRealClass;

public:
 Handle();
 ~Handle();
 // other interface
};

#endif

// realClass.cpp文件
#include "handle.h"

struct  Handle::RealClass  // 实际类的定义
{
 int  m_data;
};

Handle::Handle()
{
 m_pRealClass = new RealClass();
}

Handle::~Handle()
{
 delete m_pRealClass;
 m_pRealClass = 0;
}
以上使用了句柄类,当实际类RealClass的定义发生改变时,由于handle.h文件没有改变,所以包含handle.h的

cpp文件都不需要重新编译。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值