C++ 友元类

C++可以将类作为友元

友元类的所有方法都可以访问原始类的私有成员和保护成员,另外,也可以做更严格的控制,只将特定的成员函数指定为另一个类的友元,即友元类的某个成员函数可以访问原始类的私有成员和保护成员,其它的成员函数则不可以

友元函数或友元类要先在原始类中声明,即只能由原始类定义,而不能从外部强加友情

因此,尽管友元被授予从外部访问类的私有成员和保护成员的权限,但并不与面向对象的编程思想相悖,相反,它提高了公有接口的灵活性


问题1:什么时候希望一个类是另一个类的友元呢?

遥控器和电视机,遥控器不是电视机,电视机也不是遥控器,不符合is-a关系(公有继承)

遥控器不是电视机的一部分,电视机不是遥控器的一部分,不符合has-a关系(包含、私有继承或保护继承)

遥控器和电视机的关系:遥控器可以改变电视机的状态,即遥控器类可以改变电视机类的属性(电视机的私有成员或保护成员)


问题2:友元类的声明位置?让整个类成为友元不需要前向声明,友元本身已经指出Remote是一个类

friend class Remote;

此声明可位于公有、私有、或保护部分,所在位置无关紧要

class Tv

{

   private:   //位置1:friend class Remote;

   protected:  //位置2

   public:     //位置3

}

class Remote

{

public:

bool volup(Tv &t)

{return t.volup()}; //volup()方法使用的是Tv类的公有接口实现的,这个方法不是真正需要作为友元(因为没有访问Tv类的 私有或保护成员)

void set_chan(Tv &t,int c)//这个方法需要访问Tv类的私有成员channel,所以这个方法是需要作为友元的方法

{t.channel=c;};   //解决办法:仅让特定的类成员成为另一个类的友元,而不必让整个类成为友元

......

}

Remote类中提到了Tv类,所以编译器必须先了解Tv类后,才能处理Remote类

因此:最简单的方法是先定义Tv类

      另一种方法是使用向前声明


问题3:怎样让特定的类成员成为成为另一个类的友元,而不必让整个类成为友元?必须要有前向声明

例子:将Remote::set_chan()成为Tv类的友元方法,在Tv类中将其声明为友元

class Tv

{

  friend void Remote::set_chan(Tv &t,int c);

  ......

}

问题1>:要让编译器能够处理这条语句,它必须知道Remote的定义,否则它无法知道Remote是一个类,而set_chan()是这个类的方法

意味着,应将Remote的定义放在Tv定义前面

问题2>:Remote的方法提到了Tv对象,

意味着:Tv定义应放在Remote定义前面

解决办法---前向声明

class Tv;

class Remote{}; 

class Tv{};

能否这样声明呢?

class Remote; //不能

class Tv{};  //原因:Tv类的声明中包含Remote的一个方法set_chan()

class Remote{};//若要通过编译,Tv中应能看到Remote的声明和set_chan()方法的声明,显然只能看到Remote声明,但看不到set_chan()声明

问题3>Remote类中有方法

bool volup(Tv &t)

{return t.volup()}; //而Tv.volup()此时还没有定义,怎么解决?

解决办法:使Remote中只包含方法声明,具体的定义放在Tv类之后

class Tv;

class Remote{bool volup(Tv &t)}; //此时只需看到Tv声明即可,不需要知道具体方法

class Tv{...};

bool Remote::volup(Tv &t){return t.volup();} //当编译器看到此处真正的方法定义时,已读取了Tv的声明,并拥有了编译这些方法所需的信息

注:通过在方法前加inline同样可以使其成为内联函数






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值