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

news2024/11/27 18:49:05

目录

简介:

友元:

全局函数做友元

类做友元

成员函数做友元

运算符重载

加号运算符重载

代码示例:

输入输出运算符重载

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1456356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

苹果电脑深度清理工具CleanMyMac X2025中文版

苹果电脑用户们&#xff0c;你们是否经常感到你们的Mac变得不再像刚拆封时那样迅速、流畅&#xff1f;可能是时候对你的苹果电脑进行一次深度清理了。在这个时刻&#xff0c;拥有一些高效的深度清理工具就显得尤为重要。今天&#xff0c;我将介绍几款优秀的苹果电脑深度清理工具…

建立流行病预警指数体系并优化传染病模型:对公共卫生突发事件监测数据的分析

应对紧急情况造成的损害的能力是紧急能力现代化的重要象征。 在应对紧急情况时&#xff0c;政府机构和决策者需要更多信息来源&#xff0c;以更有效地估计灾难可能的演变。 这篇论文提出了一个预测COVID-19动态演变的优化模型&#xff0c;该模型将系统动力学的传播算法与预警指…

Windows如何打开投影到此电脑

1.首先点开设置 找到系统 点击投影到此电脑&#xff0c;如果这3行都显示灰色说明没有开启。 2.如何开启投影到此电脑 ①回到设置&#xff0c;点击应用 ②点击可选应用 ③ 安装无线显示器 投影设置可以和我一样

IP地址证书

IP地址证书&#xff0c;顾名思义&#xff0c;是一种用于验证互联网协议&#xff08;IP&#xff09;地址所有权的数字证书。它类似于网站的安全套接字层&#xff08;SSL&#xff09;证书&#xff0c;但专门用于确认和保障IP地址的所有者身份。这种证书由权威的证书颁发机构&…

【Jvm】性能调优(拓展)Jprofiler如何监控和解决死锁、内存泄露问题

文章目录 Jprofiler简介1.安装及IDEA集成Jprofiler2.如何监控并解决死锁3.如何监控及解决内存泄露(重点)4.总结5.后话 Jprofiler简介 Jprofilers是针对Java开发的性能分析工具(免费试用10天), 可以对Java程序的内存,CPU,线程,GC,锁等进行监控和分析, 1.安装及IDEA集成Jprofil…

proteus8.15图文安装教程

proteus8.15版本可以用STM32系列单片机来进行仿真设计&#xff0c;比7.8版本方便多了&#xff0c;有需要的朋友们可以在公众号后台回复 proteus8.15 获取软件包。 1、下载好软件包&#xff0c;解压如下&#xff0c;右键proteus8.15.sp1以管理员身份运行。 2、第一次安装&#x…

YOLOv6 学习笔记

概况 yolov6 出来的时候 yolov7 已经出了。 YOLOv6设计主要包含以下几个方面&#xff1a; 网络架构设计&#xff1a;对于Backbone和Neck&#xff0c;延续了YOLOv4和YOLOv5的PAN架构思想并使用了重参思想进行了改进&#xff1b;关于Head部分&#xff0c;作者对Decoupled Hea…

【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数

前言 嘿伙计们&#xff01;准备好了吗&#xff1f;今天我要和你们探讨一个酷炫的话题——Oracle数据库&#xff01;&#x1f389; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;二&#xff09;&#xff1a;体系结构、存储结构与各类参数&#xff0c;我们要揭开Oracle数据库…

IDEA中创建web项目(配置tomcat,tomcat启动报程序包javax.servlet.http不存在,tomcat控制台乱码问题)

文章目录 一、新建动态web项目1、新建项目2、选择创建动态web项目3、项目命名4、编辑index.jsp 二、配置Tomcat1、新增tomcat服务器配置2、选择服务器类型3、配置服务器参数4、部署项目5、完成配置6、启动运行7、访问web项目 三、tomcat启动报程序包javax.servlet.http不存在四…

基于ESP32+Platformio的物联网RTOS_SDK-CC_Device

本项目基于ESP32以及Platformio平台开发&#xff0c;请自行查阅如何配置这个环境 开源gitee地址&#xff1a;cc_smart_device 如果愿意贡献项目or提出疑问和修改的&#xff0c;请在gitee上提issue 项目里的mqtt服务器是公共的 请大家最好换成私有的 否则容易收到其他用户的错误…

Tomcat版本号泄露

1.问题描述 Tomcat报错页面泄漏Apache Tomcat/7.0.92相关版本号信息&#xff0c;是攻击者攻击的途径之一。因此实际当中建议去掉版本号信息。 2.测试过程 随便访问一个tomcat不存在的界面 http://127.0.0.1:8080/examples/mytest.jsp 3.解决办法 1.进入到tomcat/lib目录下&a…

C# 12 中新增的八大功能你都知道吗?

一、主构造函数 在 Visual Studio 2022 版本 17.6 预览版 2 中引入。 从 C# 12 开始&#xff0c;可以在类和结构中声明主构造函数。主构造函数参数都在类的整个主体的范围内。为了确保显式分配所有主构造函数参数&#xff0c;所有显式声明的构造函数都必须使用 this() 语法调用…

Docker部署开源白板工具Excalidraw并结合内网穿透远程访问

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1. 安装Docker2. 使用Docker拉取Excalidraw镜像3. 创建…

【Web】CTFSHOW java反序列化刷题记录(部分)

目录 web846 web847 web848 web849 web850 web856 web857 web858 web846 直接拿URLDNS链子打就行 import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.lang.reflect.F…

Postgresql 怎么实现在局域网中访问

安装PostgreSQL后&#xff0c;默认情况下只能在本机进行连接访问&#xff0c;如果需要在其他主机上访问PostgreSQL数据库服务器&#xff0c;需要进行配置。 安装连接PostgresSQL数据库可以参考博文&#xff1a;安装连接PostgresSQL数据库教程 一. 整体步骤 主要包括下面几个步…

Unity3D Shader 素描风格渲染管线实现详解

前言 在游戏开发中&#xff0c;渲染效果是非常重要的一部分&#xff0c;它可以直接影响游戏的视觉效果和玩家的体验。而素描风格的渲染效果是一种非常独特和有趣的风格&#xff0c;可以为游戏增添一种艺术氛围。在Unity3D中&#xff0c;可以通过编写Shader来实现素描风格的渲染…

家中R4S软路由iStoreOS配置内网穿透服务实现远程访问公司电脑桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…

Deepin基本环境查看(十一)[补齐碎片之旅(中)-基本附件(输入法、记事本、写字板、计算器、画图、播放器、浏览器、远程桌面)

Deepin基本环境查看&#xff08;十一&#xff09;[补齐碎片之旅&#xff08;中&#xff09;-基本附件&#xff08;输入法、记事本、写字板、计算器、画图、播放器、浏览器、远程桌面&#xff09;] - 相关文章目录1、概述2、基础附件1&#xff09;输入法2&#xff09;记事本3&am…

天然肠衣市场分析:预计到2025年将达到45亿美元

肠衣作为包装香肠馅料的原材料一般分为可食用和不可食用两种&#xff0c;其中天然肠是由猪、羊等家畜多层肠道制作而成的&#xff0c;近些年来天然肠衣在全球市场需求不断增加。一、全球市场分析 1. 市场规模&#xff1a;根据市场研究机构的数据&#xff0c;2019年全球天然肠衣…

【Prometheus】node-exporter、server、Grafana安装与配置

基于Prometheus和K8S构建智能化告警系统 一、Prometheus对kubernetes的监控二、node-exporter组件安装和配置2.1、node-exporter介绍2.2、安装node-exporter【1】拉取镜像【2】编写yaml文件【3】运行pod【4】获取数据 三、Prometheus server安装和配置3.1、创建sa账号&#xff…