欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
创意组合——friend class + virtual class member
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 

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,其友元关系的对象及其派生类都可以其友元对象派生类的私有方法。


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步