问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C++友元函数详解:如何利用友元进行运算符重载

创作时间:
作者:
@小白创作中心

C++友元函数详解:如何利用友元进行运算符重载

引用
CSDN
1.
https://blog.csdn.net/m0_75266675/article/details/139140723

在C++中,类的私有成员只能通过公有方法访问,但有时这种限制过于严格,不适合特定的编程问题。为了解决这个问题,C++提供了友元(friend)机制,允许特定的函数或类访问另一个类的私有成员。本文将通过一个具体的例子,详细介绍如何使用友元函数进行运算符重载。

友元函数的基本使用

创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend。例如,在Time类中,如果需要实现一个友元函数来重载乘法运算符,应该这样声明:

friend Time operator *(double m, const Time& t);

第二步是编写函数定义。由于友元函数不是类成员函数,因此不需要使用Time::限定符,同时在定义中也不需要使用friend关键字。例如:

Time operator *(double m, const Time& t)
{
    int minus = int(m*(t.hours*60+t.minutes));//直接使用私有成员t.hours和t.minutes
    return Time(minus / 60, minus % 60);
}

完整代码示例

下面是一个完整的Time类的实现,展示了如何使用友元函数进行运算符重载:

class Time
{
private:
    int hours;//小时
    int minutes;//分钟
public:
    Time(int h = 0, int m = 0);
    Time operator +(const Time& t)const;//重载+,注意返回值不是引用
    Time operator -(const Time& t)const;
    Time operator *(double n)const;
    void show() const;
    friend Time operator *(double m, const Time& t);//友元函数
};

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

Time Time::operator +(const Time& t) const//返回的是临时变量,不能写引用
{
    return Time(hours + t.hours + (minutes + t.minutes) / 60, (minutes + t.minutes) % 60);
}

Time Time::operator -(const Time& t)const
{
    int minu1 = hours * 60 + minutes;//把this的时间转为分钟
    int minu2 = t.hours * 60 + t.minutes;//把t的时间转为分钟
    return Time((minu1 - minu2) / 60, (minu1 - minu2) % 60);
}

Time Time::operator *(double n)const
{
    int minu = hours * 60 + minutes;//把this的时间转为分钟
    minu = int(minu * n);//分钟取整
    return Time(minu / 60, minu % 60);
}

void Time::show() const
{
    cout << hours << "小时," << minutes << "分钟" << endl;
}

Time operator *(double m, const Time& t)
{
    int minus = int(m * (t.hours * 60 + t.minutes));//直接使用私有成员t.hours和t.minutes
    return Time(minus / 60, minus % 60);
}

int main()
{
    Time t1 = { 2,35 };
    Time t2 = 3 * t1;//数字写在前,编译器转为t2=operator*(3,t1);
    t2.show();
    return 0;
}

更简洁的实现方式

实际上,还有更简洁的方法来实现友元函数。利用乘法交换律,可以把友元函数改为非友元函数:

Time operator *(double m, const Time &t)
{
    return t*m;//利用t的成员函数.    
}

这种方法更简单,但友元函数实现也是一个好主意,它将作为类接口的组成部分。

总结

当需要为类重载运算符时,可以采用以下策略:

  1. 定义第一个操作数为类对象的成员函数
  2. 添加一个第一个操作数为非类对象的友元函数
  3. 在友元函数内部,利用交换律调用类成员函数(前提是运算符满足交换律)

如果运算符重载函数需要访问类的私有数据,可以采用以下方法:

  1. 利用交换律(前提是类已经实现该运算符的重载)
  2. 将函数声明为类的友元函数
  3. 提供获取私有数据的公有方法

通过本文的讲解和示例代码,相信读者能够掌握C++中友元函数的基本使用方法及其在运算符重载中的应用。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号