|
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> using namespace std; class a { friend class b; public: a():_a("hello"){} ~a(){} void printA() { cout << _a << endl;} private: string _a; }; class b { public: void BprintA(a* _a) { cout << _a->_a << endl;} protected: string& getA(a* _a){return _a->_a;} }; class c : public b { public: void CsetA(a* _a) { string& a_str = getA(_a); a_str = "haha"; } }; int main() { 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 return 0; } class a的私有成员是访问到了,但是我想访问继承自class a的派生类的私有成员呢? 也许你没有明白,也许你认为不实用。那好吧,为了证明我不是讨论些没有用的技术,我结合个实例来说吧。
我要实现一个处理事件机制的问题。因为由于event的生命周期由程序来控制,它必须要用new来生成,用delete来释放。而且是由observer处理完之后才释放。为了防止程序员在observer之外意外的delete掉event,我将event的析构函数设为protected。为了防止程序员没有用new来生成对象,我将构造函数也设为protected,提供一个静态方法create()来产生event对象,并返回指针。于是变为下图:
可是问题来了,observer要delete对象event,必须把observer设为event的友元类。 可是真正生成的event对象是它的派生类,真正处理event的也不是observer,而是它的派生类。但是根据event-observer设计模式的原则,实作一个event根本不用关心它的observer对象是哪位。 解决办法很简单,将event的析构函数设为virtual(事实上也应该设为virtual)。问题解决了。如下图:
总结: 这说明了两个问题 1. 派生类可以通过基类的方法操作友元对象的私有成员。 2. 如果友元对象的私有方法设为virtual,其友元关系的对象及其派生类都可以其友元对象派生类的私有方法。
|