友元类

  类并非只能拥有友元函数,也可以将类作为友元。这样友元类的所有方法都可以访问原始类的私有成员和保护成员。另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元。
友元声明可以位于公有、私有或保护部分,其所在的位置无关紧要。
下面给一个友元类的例子:

class Tv
{
    int state;
    int volume;
    int maxchannel;
    int channel;
    int mode;
    int input;

public:
    friend class Remote;
    enum {Off, On};
    enum {MinVal, MaxVal = 20};
    enum {Antenna, Cable};
    enum {TV, DVD};

    Tv(int s = Off, int mc = 125) : state(s), volume(5),
        maxchannel(mc), channel(s), mode(Cable), input(TV) {}
    ~Tv() {};
    void onoff() {state = (state == On) ? Off : On;}
    bool ison() const {return state == On;}
    bool volup();
    bool voldown();
    void chanup();
    void chandown();
    void set_mode() {mode = (mode == Antenna) ? Cable : Antenna;}
    void set_input() {input = (input == TV) ? DVD : TV;}
    void setting() const;
};

class Remote
{
    int mode;
public:
    Remote(int m = Tv::TV) : mode(m) {}
    bool volup(Tv & t) {return t.volup();}
    bool voldown(Tv & t) {return t.voldown();}
    void onoff(Tv & t) {t.onoff();}
    void set_chan(Tv & t, int n) {t.channel = n;}
    void chanup(Tv & t) {t.chanup();}
    void chandown(Tv & t) {t.chandown();}
    void set_mode(Tv & t) {t.set_mode();}
    void set_input(Tv & t) {t.set_input();}
};

从例子中的代码可知,大多数的Remote方法都是用Tv类的公有接口实现的。这意味着这些方法不是真正需要作为友元。唯一需要作为友元的方法是直接访问Tv类成员的函数set_chan(),如果只让该方法作为类的友元,必须小心排列类中各种声明和定义的顺序。

void set_chan(Tv & t, int n) 

类Tv是set_chan的参数,所以Tv声明应在Remote之前,但是Tv中又提到了Remote,这意味着Remote应在Tv之前。这就有些矛盾了
避开这种循环依赖的方法是:使用向前声明

class Tv;
class Remote {......};
class Tv {.....};

不能像下面这样排列

class Remote;
class Tv {.....};
class Remote {......};

编译器在Tv类的声明中看到Remote的一个方法被声明为Tv类的友元之前,应该先看到Remote类的声明和set_chan()方法的声明。
还有一个问题,Remote声明包含了内联代码,例如:

void chanup(Tv & t) {t.chanup();}

这将调用一个Tv的方法,所以编译器这时必须已经看到了Tv类的声明。结果是Tv声明位于Remote声明的后面,解决这个问题的办法是,使Remote声明中只包含方法的声明,并将实际的定义放在Tv类之后。

class Tv;
class Remote {......};
class Tv {.....};

inline void Remote::chanup(Tv & t) {t.chanup();}//依然是内联的

共同的友元
  需要使用友元的另一种情况是,函数需要访问两个类的私有数据。这时可以将同一个函数声明为两个类共同的友元函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值