c++入门学习⑥——友元和运算符重载

目录

简介:

友元:

全局函数做友元

类做友元

成员函数做友元

运算符重载

加号运算符重载

代码示例:

输入输出运算符重载

⭐cin

⭐cout

代码示例:

分析:

自增运算符重载

代码示例(成员函数实现):

分析:

==运算符重载

代码示例:

分析:

函数调用运算符()重载

代码示例:

以上的运算符完整重载代码:

总结:


简介:

介绍有关友元和运算符重载的知识,运算符重载根据介绍

友元:

1.类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。

⭐注意:友元函数并不是成员函数👉尽管友元函数的原型有在类的定义中出现了。

2.友元可以是一个函数,该函数被称为友元函数友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

3.如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend

全局函数做友元

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std; 
//友元,有些私有的属性想要类外的某些函数或者是类来访问,就需要友元
//friend
//实现三种:全局函数做友元
class building {//建筑物类
    friend void test(building& build);//实现全局函数可以访问私有成员了
public:
    building() {
        m_sittingroom = "客厅";
        m_bedroom = "卧室";
    }
public:
    string m_sittingroom;
private:
    string m_bedroom;
};
//引用或者指针传入
 void test(building &build)//全局函数,可以访问私有成员
{
     cout << "访问公共属性" << build.m_sittingroom<<endl;//运行成功
     cout << "访问私有属性" << build.m_bedroom << endl;//加上类中的第一行代码之后就可以正常运行了
}
 void test1() {
     building build;
    test(build);
 }
int main()
{
    test1();
    system("pause");
    return 0;
}

类做友元

#include<iostream>
#include<string>
using namespace std; 
//友元,有些私有的属性想要类外的某些函数或者是类来访问,就需要友元
//friend为关键字
//实现:类做友元,类可以访问另一个类的私有属性

class building {//建筑物类
    //good friend是本类的好朋友,
    friend class goodfriend;
public:
    building();
    string m_sittingroom;
private:
    string m_bedroom;
};

building::building() {//构造函数赋初值
    m_sittingroom = "客厅";
    m_bedroom = "卧室";
}

class goodfriend{//好朋友类
public:
    goodfriend();
    void visit();//在类外创建函数,则要在类内进行声明
    building* build;
};

goodfriend::goodfriend() {//创建建筑物对象
    build = new building;//在堆区创建
}

void goodfriend::visit()//参观函数,访问另一个类的属性
{
    cout << "好朋友类访问公共属性" << build->m_sittingroom << endl;
    cout << "好朋友类访问私有属性" << build->m_bedroom << endl;
}

 void test1() {//测试案例代码
     goodfriend f;//创建一个类对象后会先调用构造函数good friend(),这个函数里面有building另外一个类的对象创建,则调用building这个类的构造函数
     f.visit();//使用类函数则要先创建类对象,然后调用类里的函数声明。
 }
 //类外写成员函数

int main()
{
    test1();
    system("pause");
    return 0;
}

成员函数做友元

注意先声明building然后再定义朋友类,再定义建筑物类,再利用构造函数初始化朋友类,创建类对象,然后构造函数赋初值给类属性,重要的是,要先定义朋友类,再定义建筑类,不然程序会出错的。

#include<iostream>
#include<string>
using namespace std; 
//友元,有些私有的属性想要类外的某些函数或者是类来访问,就需要友元
//friend为关键字
//实现:成员函数做友元
class building;

class goodfriend{//好朋友类
public:
    goodfriend();
    void visit1();//可以访问私有内容
    void visit2();//只能访问公共内容
    building* build;
};


class building {//建筑物类
    //告诉编译器这个类下面的visit1函数作为本类的好朋友,可以访问私有内容
    friend void goodfriend::visit1();
public:
    building();
    string m_sittingroom;
private:
    string m_bedroom;
};
goodfriend::goodfriend() {//创建建筑物对象
    build = new building;//在堆区创建
}
building::building() {//构造函数赋初值
    m_sittingroom = "客厅";
    m_bedroom = "卧室";
}

void goodfriend::visit1() {
    cout << "访问类的公共属性:" << build->m_sittingroom << endl;
    cout << "访问私有属性:" <<build->m_bedroom<< endl;
}
void goodfriend::visit2() {
    cout << "访问类的公共属性:" << build->m_sittingroom << endl;
}
 void test1() {//测试案例代码
     goodfriend f;//创建一个类对象后会先调用构造函数good friend(),这个函数里面有building另外一个类的对象创建,则调用building这个类的构造函数
     f.visit1();
     f.visit2();
 }
 //类外写成员函数

int main()
{
    test1();
    system("pause");
    return 0;
}

运算符重载

对于内置的数据类型,编译器知道如何运算。

而c++中有自定义数据类型,程序往往不知道如何去计算自定义数据类型

因此需要自己进行运算符重载,使用关键字operate

加号运算符重载

先新建一个自定义数据类型——类,然后对于类对象的直接相加计算机不知道如何计算——》需要进行加号运算符重载

代码示例:

这个是使用成员函数重载的+号运算符

由于是两个类对象直接相加,所以这里新建一个类对象让成员分别相加,最后返回person类型,这里的this指针是指向调用这个函数的类对象例如式子为p1+p2,则p1调用这个函数,并传入p2。

    //成员函数重载+运算符
person operator+(person &p)
{
   person t;
   t.m_age = this->m_age + p.m_age;
   t.m_high = this->m_high + p.m_high;
   return t;
}

 全局函数重载+运算符,这里是把两个类对象直接传入,不用this指针了。

//全局函数重载+运算符
person operator+(person p1, person p2)
{
    person t;
    t.m_age = p1.m_age + p2.m_age;
    t.m_high = p1.m_high + p2.m_high;
    return t;
}

输入输出运算符重载

这里需要知道两个流,在c++中cin和cout是输入输出最基本的符号

⭐cin

cin的类型是istream也就是说cin是一个istream类型的对象

⭐cout

cout类型为ostream,不是函数

istreamostreamiostream库中最常用的两个基础类型,本别为输入流和输出流(流为字符序列,主要操作对象为IO

🆗基本知识了解后我们就可以写运算符重载函数了

代码示例:

分析:

首先对于<<运算符重载,第一先判定需要完成的功能——输出类对象的所有成员

由上图可知,参数1为cout,参数2为输出对象——类对象p

而返回值是怎么定的呢?由于会存在链式输出,当一个<<完成后返回值如果是类则无法输出如下图:

则>>运算符重载同理,也是先判断要完成的功能和参数,然后根据实际案例,确定返回值,即可完成运算符重载。

//重载<<运算符
ostream& operator<<(ostream&cout,const person& p)
{
    cout << p.m_age<<" ";
    cout << p.m_high <<endl ;
    return cout;
}

//重载>>运算符
istream& operator>>(istream& cin, person& p)//这里不和重载<<运算符一样,不要加const
{
    cin >> p.m_age;
    cin >> p.m_high;
    return cin;
}

自增运算符重载

自增运算符分为两种——++a,a++

代码示例(成员函数实现):

分析:

首先我们要完成的是前缀的自增运算符,完成功能是要先把所有类对象的成员+1然后返回所有成员加一后的类对象

而后缀是需要先返回值再加值,而这一个不能先写return再加一,无法操作,那么这里可以借助新建一个类对象来对过去的数据进行存储,返回这个旧数据,而把调用这个函数的类对象的成员值增加1

为了区分两个自增运算符重载,对于后缀的参数里加(int),前缀的无参数

//重载后缀的自增运算符
person operator++(int)
{
    person t;
    t.m_age = this->m_age++;
    t.m_high = this->m_high++;
    return t;
}
//重载前缀的自增运算符
person operator++()
{
    ++this->m_age;
    ++this->m_high;
    return *this;
}

==运算符重载

代码示例:

分析:

这里要实现的功能是判断两个类对象是否相等,参数是判断两个关系的类对象,返回值为布尔类型,在运算符重载函数中需要写if语句,通过判断两个的成员是否相等来判断两个类对象是否相等

//重载==关系运算符
bool operator==(person p1,person p2)
{
    if (p1.m_age == p2.m_age&& p1.m_high == p2.m_high)
    {
        return 1;
    }else
    {
        return 0;
    }
}

函数调用运算符()重载

代码示例:

这里示例是要实现调用的类对象加上传进去的两个整型数据,然后返回。

//函数调用重载
person operator()(int a,int b)
{
    this->m_age  = this->m_age +a;
    this->m_high  = this->m_high +b;
    return *this;
}

以上的运算符完整重载代码:

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
using namespace std; 
class person
{
public:
    int m_age;
    int m_high;
    //成员函数重载+运算符
//person operator+(person &p)
//{
 //   person t;
 //   t.m_age = this->m_age + p.m_age;
 //   t.m_high = this->m_high + p.m_high;
 //   return t;
//}
    //重载后缀的自增运算符
    person operator++(int)
    {
        person t;
        t.m_age = this->m_age++;
        t.m_high = this->m_high++;
        return t;
    }
    //重载前缀的自增运算符
    person operator++()
    {
        ++this->m_age;
        ++this->m_high;
        return *this;
    }
    //函数调用重载
    person operator()(int a,int b)
    {
        this->m_age  = this->m_age +a;
        this->m_high  = this->m_high +b;
        return *this;
    }
};
//全局函数重载+运算符
person operator+(person p1, person p2)
{
    person t;
    t.m_age = p1.m_age + p2.m_age;
    t.m_high = p1.m_high + p2.m_high;
    return t;
}
//重载关系运算符
bool operator==(person p1,person p2)
{
    if (p1.m_age == p2.m_age&& p1.m_high == p2.m_high)
    {
        return 1;
    }
}
//重载<<运算符
ostream& operator<<(ostream&cout,const person& p)
{
    cout << p.m_age<<" ";
    cout << p.m_high <<endl ;
    return cout;
}
//重载>>运算符
istream& operator>>(istream& cin, person& p)//这里不和重载<<运算符一样,不要加const
{
    cin >> p.m_age;
    cin >> p.m_high;
    return cin;
}

void test1() {
    person p1;
    person p2;
    person p3;
    p1.m_age = 12;
    p1.m_high = 153;
    p2.m_age = 18;
    p2.m_high = 192;
    cout<<p1 + p2;
    cout << p1++;//12 153
    cout << p1;//13 154
    cout << ++p2;//19 193
    cin >> p3;//19 193
    if (p2 == p3) {
        cout << "你们身高和年龄一样啊" << endl;
    }
    person p4 = p3(10, 20);//29 213
    cout << p4;//29 213
}
int main()
{
    test1();
    system("pause");
    return 0;
}

总结:

对于c++的友元以及运算符重载就介绍到这里,欢迎点赞收藏文章和专栏(会分享更多代码知识),文章如有错误,请大佬指出,谢谢(●'◡'●)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值