C++程序设计——六

本文通过一个实验详细介绍了C++中运算符重载,特别是类外重载和友元函数的使用。友元函数允许外部函数访问类的私有和保护成员,使得能够实现如加减乘除等运算符的重载。同时,通过友元函数重载‘<<’运算符,使得能方便地输出类对象的属性。实验结论强调了类外重载和友元函数在访问私有成员和实现特定功能上的重要性。
摘要由CSDN通过智能技术生成

实验目的

学习并掌握C++运算符类外重载即友元函数相关的内容

实验内容

在C++中,类的友元函数定义在类外部,但它有权访问类的所有私有成员(private)和保护成员(protected)。
尽管友元函数的原型有在类的定义中出现过,但友元函数和成员函数并不相同。

为什么要使用友元函数?

我们来看这样一种情况,对于两个类,A和B,A显然可以允许B的函数访问A的公有成员,但若是想要B的函数也可以访问A的私有成员,显然不借助其他手段是无法做到的。
这个时候,就需要友元函数。

友元函数的使用

如果一个类想把一个函数作为它的友元,只需要增加一条friend关键字开始的函数声明语句即可。如下:

#include <iostream>
using namespace std;

class num
{
public:
    num operator+(const num& y)
    {
        num temp;
        temp.lenth=this->lenth+y.lenth;
        temp.width=this->width+y.width;
        return temp;
    }
    num operator-(const num& y)
    {
        num temp;
        temp.lenth=this->lenth-y.lenth;
        temp.width=this->width-y.width;
        return temp;
    }
    num operator*(const num& y)
    {
        num temp;
        temp.lenth=this->lenth*y.lenth;
        temp.width=this->width*y.width;
        return temp;
    }
    num operator/(const num& y)
    {
        num temp;
        temp.lenth=this->lenth/y.lenth;
        temp.width=this->width/y.width;
        return temp;
    }
    num operator=(const num& y)
    {
        int ss=y.lenth;
        cout<<"使用了重载后的=运算符,右值的lenth为"<<ss<<endl;
        this->width=y.width;
        this->lenth=y.lenth;
        return *this;
    }

    int lenth;
    int width;
    friend void printt(const num& y);
private:
    double height=11.2;
    


};
void printt(const num& y)
{
    cout<<"访问私有成员,height:"<<y.height<<endl;
}
int main()
{
    num z;
    printt(z);
}

因为printt是类num的友元函数,所以它可以访问num对象的私有成员height;

重载<<运算符

在这里插入图片描述
通过友元函数重载"<<"运算符,可以使得<<输出类的对象的属性只需要

cout<<z<<endl;

如上图
但仅仅如此还是不够的,试想下面一种情况
在这里插入图片描述
这样是不行的,这和我们之前讲过的类内重载=运算符的情况颇为相似,因为我们前面定义的<<重载仅仅是输出类的属性,却不能返回一个os对象,这使得它后面跟着其他内容即

cout<<z<<"其他内容";

这样时,<<无法识别左值z,那么就无法正常调用原来的<<运算符输出z后面的内容,我们只需要按照原来<<运算符的格式,将的返回值类型设置为一个ostream的引用即可(为什么返回值使用引用在上一篇文章已经介绍过,这里不再重复),这样就能正常调用原来的<<运算符了,如下
在这里插入图片描述
下面是完整代码

#include <iostream>
using namespace std;

class num
{
public:
    num operator+(const num& y)
    {
        num temp;
        temp.lenth=this->lenth+y.lenth;
        temp.width=this->width+y.width;
        return temp;
    }
    num operator-(const num& y)
    {
        num temp;
        temp.lenth=this->lenth-y.lenth;
        temp.width=this->width-y.width;
        return temp;
    }
    num operator*(const num& y)
    {
        num temp;
        temp.lenth=this->lenth*y.lenth;
        temp.width=this->width*y.width;
        return temp;
    }
    num operator/(const num& y)
    {
        num temp;
        temp.lenth=this->lenth/y.lenth;
        temp.width=this->width/y.width;
        return temp;
    }
    num operator=(const num& y)
    {
        int ss=y.lenth;
        cout<<"使用了重载后的=运算符,右值的lenth为"<<ss<<endl;
        this->width=y.width;
        this->lenth=y.lenth;
        return *this;
    }

    int lenth;
    int width;
    friend void printt(const num& y);
    friend ostream& operator<<(ostream & os, const num& y);
private:
    double height=11.2;
    


};
void printt(const num& y)
{
    cout<<"访问私有成员,height:"<<y.height<<endl;
}

ostream& operator<<(ostream & os, const num& y)
{
    os<<"width:"<<y.width<<",length:"<<y.lenth<<endl;
    return os;
}

int main()
{
    num z;
    printt(z);
    z.lenth=12;
    z.width=13;
    cout<<"z的属性:"<<z<<endl;;
}

实验结论

经过这次实验,我们掌握了类外重载的用法,它和类内重载的区别在于它不是类的成员函数,而是仅仅在类内做一个友元声明,在类外定义,这样它就能访问类的私有成员了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值