C++友元(友元函数)

1.1为何需要友元

我们知道C++的类中访问权限分public,protected,private。当我们想通过类方法进行访问的时候往往是在public的区域写一个函数来访问。但是这种方式过于严格拉,所以C++就有了友元。

友元友元,就是类的好朋友,可以用用他的数据啦。

1.2举一个重载的例子说明其重要性

随手写的一个Time例子,在此类中重载了*号运算符,使*能让对象与一个int类的数相乘,使min变成原来的a倍,并且返回这个T类。


class T {
private:
    int hours;
    int minutes;
public:
    T();
    T(int h, int m=0);
    void show() const;
    T operator*(int a) const;    //类内重载*号
};

T T::operator*(int a) const {
    T cheng;
    cheng.hours = this->hours;
    cheng.minutes = this->minutes * a;

    return cheng;
}

于是便可以愉快的调用啦,如下代码所示调用,可以发现time*3是对的,但三3*time是错的??

Why??为森么呢,在我们的直观感觉上,进行了重载*号,两个东西相乘,交换一下应该是没有区别的。但是C++并不是这样的!

记住:左侧的操作数应该是调用对象!左侧的操作数应该是调用对象!左侧的操作数应该是调用对象!

因此time*3这种表达对应于我们刚刚写的成员函数,time为调用对象,而3并不是调用对象!所以是错误的。

int main() {

T time(12,30);
T now(2,30);
T mm = time*3;//这样是对的
T nn = 3*time;//这样是错的哦
mm.show();
nn.show();
    return 0;
}

1.3解决方法

如果按上面说的,我们重载了运算符但是也只能这样用,不能交换,其不是很麻烦?

我们当然可以告诉我们的程序员,我们必须按照 对象*数字 这种方式写,但这是一种服务器友好-客户警惕(server-friednly,client-beware)的解决方案。我们能不能遵从内心,用数字*对象这种方式写呢。答案是可以的。我们使用非成员函数。



class T {
private:
    int hours;
    int minutes;
public:
    T();
    T(int h, int m=0);
    void show() const;
    T operator*(int a) const;    //
    friend T operator*(double m,const T &t) ;//友元在类中声明一下,但是不属于类
};

T T::operator*(int a) const {
    T cheng;
    cheng.hours = this->hours;
    cheng.minutes = this->minutes * a;

    return cheng;
}
T operator*(double m,const T& t) //注意这里,这里的operator*并不是在T这个类空间中的
{
    T temp;
    temp.minutes = m*t.minutes;
    return temp;
}

 如上所示,我们就可以 T nn = 3*time了,这样做就会匹配到这个函数。是不是非常方便?

注意:1.友元函数只是在类中声明,因此在写定义的时候不要加类限定符。

           2.同上,友元函数在类中声明,但并不属于他,不是成员函数,因此不能用成员运算符来调用他。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值