创意组合——friend class + virtual class member

friend class可以让友元类访问到自己类的私有成员。

virtual class member的声明可以让程序访问到真正的对象的成员。

创意组合——friend class + virtual class member

class a声明了class c是其友元类,所以class c可以访问到class a的私有成员。

但是friend关系是不可以继承的,也就是说,class d不可以访问到class a的私有成员。有什么办法可以让继承类也能继承这种友元关系呢?

办法是有的!

如果非要让class d访问class a的成员变量,而又不能在class a中明文声明(通常API编程都是这样,因为不可能知道会有哪个类继承class c。又或者想让程序变的优雅一些,毕竟在一个类中写上太多的友元声明感觉不是很好),那可以在class c中写上getXxx函数,并让其受保护。这样,任何继承自class c的派生类都可以访问class a的私有类了,当然是通过get函数。

代码如下:

#include<iostream>

#include<string>

usingnamespacestd;

classa

{

friendclassb;

public:

a():_a("hello"){}

~a(){}

voidprintA() { cout << _a << endl;}

private:

string _a;

};

classb

{

public:

voidBprintA(a* _a) { cout << _a->_a << endl;}

protected:

string& getA(a* _a){return_a->_a;}

};

classc :publicb

{

public:

voidCsetA(a* _a)

{

string& a_str = getA(_a);

a_str = "haha";

}

};

intmain()

{

a my_a;

my_a.printA();//输出 hello

b my_b;

my_b.BprintA(&my_a);//class b可以访问 class a

c my_c;

my_c.CsetA(&my_a);//class c也成功访问 class a的私有变量

my_a.printA();//输出 haha

return0;

}

class a的私有成员是访问到了,但是我想访问继承自class a的派生类的私有成员呢?

也许你没有明白,也许你认为不实用。那好吧,为了证明我不是讨论些没有用的技术,我结合个实例来说吧。

创意组合——friend class + virtual class member

我要实现一个处理事件机制的问题。因为由于event的生命周期由程序来控制,它必须要用new来生成,用delete来释放。而且是由observer处理完之后才释放。为了防止程序员在observer之外意外的delete掉event,我将event的析构函数设为protected。为了防止程序员没有用new来生成对象,我将构造函数也设为protected,提供一个静态方法create()来产生event对象,并返回指针。于是变为下图:创意组合——friend class + virtual class member

可是问题来了,observer要delete对象event,必须把observer设为event的友元类。

可是真正生成的event对象是它的派生类,真正处理event的也不是observer,而是它的派生类。但是根据event-observer设计模式的原则,实作一个event根本不用关心它的observer对象是哪位。

解决办法很简单,将event的析构函数设为virtual(事实上也应该设为virtual)。问题解决了。如下图:创意组合——friend class + virtual class member

总结:

这说明了两个问题

1.派生类可以通过基类的方法操作友元对象的私有成员。

2.如果友元对象的私有方法设为virtual,其友元关系的对象及其派生类都可以其友元对象派生类的私有方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值