从0开始C++(五):友元函数运算符重载

 相关文章:

从0开始C++(一):从C到C++

从0开始C++(二):类、对象、封装

从0开始C++(三):构造函数与析构函数详解

从0开始C++(四):作用域限定符、this指针、static与const关键字

从0开始C++(五):友元函数&运算符重载

从0开始C++(六):模板与容器的使用

从0开始C++(七):继承

目录

友元函数

介绍

创建友元函数

 运算符重载

特殊运算符重载

1、赋值运算符重载

2、类型转换运算符重载

注意事项


友元函数

介绍

C++中的友元函数是一种特殊的函数,它可以访问和操作类的私有成员和保护成员。友元函数可以在类的内部或外部声明和定义,但在其声明和定义中需要使用关键字 friend 来标识。友元函数可以是全局函数,也可以是其他类的成员函数。

下面是友元函数的一些重要特点和用法:

  1. 友元函数可以访问和操作类的私有成员和保护成员,这使得函数可以直接访问类的私有数据,而无需通过类的公有接口进行访问。

  2. 友元函数可以在类的内部或外部声明和定义。在类的内部声明友元函数时,使用friend关键字来标识函数为友元函数。在类的外部定义友元函数时,需要在函数的定义前面声明该函数为友元函数。

  3. 友元函数可以是全局函数,也可以是其他类的成员函数。如果友元函数是另一个类的成员函数,需要在该类的声明中将其声明为友元函数。

  4. 友元函数不是类的成员函数,因此它没有隐含的this指针,也无法访问类的非静态成员。

  5. 友元函数的声明可以放在类的任何位置,但其定义必须在类的外部。这是因为友元函数不属于类的成员,所以需要在类的外部定义。

  6. 友元函数可以用于重载操作符。这使得我们能够定义两个不同类对象之间的操作,例如添加两个自定义类的对象。

友元函数提供了一种特殊的访问和操作类的私有成员和保护成员的方式。它在某些情况下可以简化代码实现,但同时也破坏了封装性,因此需要谨慎使用。

创建友元函数

要创建一个友元函数,需要按照以下步骤进行操作:

1、在类内声明友元函数:在类的声明中,使用 friend 关键字来声明友元函数。友元函数可以是全局函数,也可以是其他类的成员函数。例如,下面的代码将一个全局函数声明为类的友元函数:

class MyClass {
public:
    // 声明友元函数
    friend void myFriendFunction();
};

2、在类的外部定义友元函数:在类的外部,需要定义先前声明的友元函数。这样,友元函数就可以访问和操作类的私有成员和保护成员。例如,下面的代码定义了先前声明的友元函数:

// 定义友元函数
void myFriendFunction() {
    // 在此函数中可以访问和操作MyClass的私有成员和保护成员
}

3、使用友元函数:使用类的对象或类名和作用域解析运算符(::)调用友元函数。例如,下面的代码演示了如何使用类对象调用友元函数:

MyClass obj;
myFriendFunction();  // 使用类对象调用友元函数

或者,如果友元函数是另一个类的成员函数,可以使用该类的对象或类名和作用域解析运算符(::)调用友元函数。例如,下面的代码演示了如何使用类对象调用另一个类的成员函数作为友元函数:

class MyClass2 {
public:
    // 声明友元函数
    friend void MyClass::myFriendFunction2();
};

// 定义友元函数
void MyClass::myFriendFunction2() {
    // 在此函数中可以访问和操作MyClass2的私有成员和保护成员
}

MyClass obj;
MyClass2 obj2;
obj.myFriendFunction2();  // 使用类对象调用友元函数

 运算符重载

运算符重载是指在类中重定义运算符的行为,使其适用于特定的类对象。运算符重载可以使得类对象的使用更加自然和方便,同时也提供了更多的灵活性。

要重载运算符,需要定义一个类成员函数或全局函数来执行所需操作,该函数的名称是运算符本身,并使用 operator 关键字声明。例如,要重载"+"运算符,可以定义一个名为operator+()的函数。

以下是一个示例,演示了如何重载"+"运算符:

class MyClass {
private:
    int value;
public:
    MyClass(int v) : value(v) {}

    MyClass operator+(const MyClass& other) {  // 运算符重载函数
        return MyClass(value + other.value);
    }

    int getValue() const {
        return value;
    }
};

int main() {
    MyClass obj1(3);
    MyClass obj2(5);

    MyClass result = obj1 + obj2;  // 使用重载的"+"运算符

    std::cout << result.getValue() << std::endl;  // 输出结果:8

    return 0;
}

上述示例中,我们在MyClass类中重载了"+"运算符。重载函数声明中的参数是另一个MyClass对象(const引用),并返回一个新的MyClass对象。在main函数中,我们创建了两个MyClass对象,然后使用重载的"+"运算符将它们相加,最终得到一个新的MyClass对象。

需要注意的是,在重载运算符时,可以根据需要选择将函数定义为类成员函数全局函数(定义全局函数的时候需要将其声明为友元函数)。对于一些需要访问类私有成员的运算符,比如赋值运算符"=",通常选择将函数定义为类成员函数;对于一些不需要直接访问类私有成员的运算符,可以选择将函数定义为全局函数。

运算符重载可以大大简化代码,并提高可读性和可维护性。但是,需要谨慎使用运算符重载,以避免混淆和误用。同样,不应该过度使用运算符重载,以保持代码的简洁和易读性。

特殊运算符重载

1、赋值运算符重载
除了之前学习无参构造函数拷贝构造函数析构函数之外如果程序员手写编译器自动添加一个赋值运算符重载, 赋值运算符只能使用成员函数实现重载
当类中出现指针类型成员变量默认赋值运算符重载函数类似于默认浅拷贝构造函数因此也需要手动编写解决浅拷贝问题

【常见面试题】一个类如果什么都不编译添加了那些代码

无参构造函数拷贝构造函数析构函数赋值运算符重载函数

2、类型转换运算符重载

类型转换运算符重载允许将一个类的对象转换为另一个类型。

类型转换运算符重载的语法如下:

operator type() {
    // 进行类型转换的操作
}

其中,type是要转换的目标类型。重载的类型转换运算符可以是类的成员函数或类的非成员函数。

下面是一个示例,演示了如何重载类型转换运算符:

class MyClass {
private:
    int value;
public:
    MyClass(int v) : value(v) {}

    operator int() {
        return value;
    }
};

int main() {
    MyClass obj(42);

    int result = obj;  // 使用重载的类型转换运算符将MyClass对象转换为int

    std::cout << result << std::endl;  // 输出结果:42

    return 0;
}

在上述示例中,我们定义了一个名为MyClass的类,并在其中重载了类型转换运算符。重载函数声明中的返回类型是要转换的目标类型(int),并在函数体中返回了MyClass对象的value成员。

在main函数中,我们创建了一个MyClass对象,并将其赋值给一个int类型的变量。由于我们已经重载了类型转换运算符,所以可以直接将MyClass对象转换为int类型。最终,输出结果为42。

需要注意的是,在重载类型转换运算符时,应该在函数体中进行适当的类型转换操作,并返回目标类型的对象。此外,需要慎谨使用类型转换运算符,以避免混淆和误用。

另外,C++还提供了显式转换运算符重载(explicit conversion operator),通过在重载函数前加上 explicit 关键字来实现。这样,在使用显式转换运算符进行类型转换时,需要明确使用转换运算符进行转换。

注意事项

● 重载运算符限制在C++语言中已有运算符范围不能创建新的运算符

● 运算符重载本质上也是函数重载但是不支持函数参数默认值

● 之后运算符不能改变运算符优先级结合不能改变运算符操作数语法结构

● 运算符重载必须基于包含自定义类型不能改变基本数据类型运算规则

● 重载功能应该与原有功能类似避免没有目的滥用运算符重载

● 一般情况下双目运算符建议使用友元函数运算符重载单目运算符建议使用成员函数运算符重载

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习入门 chatgpt原理 一

学习文章&#xff1a;人人都能看懂的chatGpt原理课 笔记作为学习用&#xff0c;侵删 Chatph和自然语言处理 什么是ChatGpt ChatGPT&#xff08;Chat Generative Pre-training Transformer&#xff09; 是一个 AI 模型&#xff0c;属于自然语言处理&#xff08; Natural Lang…

视频分享的二维码怎么做?多种视频可用的二维码制作技巧

视频分享的快捷操作技巧可以在二维码生成器上来制作&#xff0c;与传统分享方式相比用二维码的方法能够更快捷&#xff0c;有利于用户能够在不下载视频占用空间的同时&#xff0c;就能够扫描二维码观看视频内容。视频二维码能够应用于很多的场景下&#xff0c;那么制作一个视频…

云服务器部署LNMP Web环境教程合集(多版linux系统安装方法)

LNMP环境包括Linux、Nginx、MySQL和PHP&#xff0c;Nginx是一款小巧而高效的Web服务器软件&#xff0c;使用阿里云服务器搭建LNMP Web网站环境很简单&#xff0c;支持多种LNMP环境部署教程&#xff0c;可使用ROS模板部署、LNMP镜像以及基于不同Linux操作系统手动部署LNMP全流程…

MeshAnything:艺术家级别的自回归3D网格生成

MeshAnything: Artist-Created Mesh Generation with Autoregressive Transformers &#x1f4dc; 文献卡 MeshAnything: Artist-Created Mesh Generation with Autoregressive Transformers作者: Yiwen Chen; Tong He; Di Huang; Weicai Ye; Sijin Chen; Jiaxiang Tang; Xin…

酒店设施和维修管理后台系统

摘 要 随着旅游业的快速发展和酒店行业的蓬勃增长&#xff0c;酒店行业成为了现代社会中不可或缺的一部分。酒店作为提供住宿、餐饮和其他服务的场所&#xff0c;需要保证设施的正常运行和及时维修&#xff0c;以提供良好的客户体验和满足客户需求。然而传统的手动管理方式往往…

「6.25更新日志」JVS·智能BI、逻辑引擎(服务编排)功能更新说明

项目介绍 JVS是企业级数字化服务构建的基础脚手架&#xff0c;主要解决企业信息化项目交付难、实施效率低、开发成本高的问题&#xff0c;采用微服务配置化的方式&#xff0c;提供了 低代码数据分析物联网的核心能力产品&#xff0c;并构建了协同办公、企业常用的管理工具等&am…

React的路由(ReactRouter)-路由导航跳转

1.第一步 // createBrowserRouter路由 RouterProvider组件 import {createBrowserRouter,RouterProvider} from react-router-dom // 创建router实例对象&#xff0c;并配置路由对应关系 const routercreateBrowserRouter([{path:/login,element:<div>我是登录页</di…

【ARM】内存属性Memory Attributes (MemAttr)

目录 1. EWA 2. Device 3. Cacheable 4. Allocate 5. 内存属性的传播 6. 事务属性组合 7. Memory Type 内存属性Memory Attributes (MemAttr) 包含Early Write Acknowledgment (EWA), Device, Cacheable, 以及Allocate。 1. EWA EWA&#xff0c;Early Write Acknowledg…

Jenkins 创建流水线任务

Jenkins是一个流行的持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;工具。 Jenkins 创建任务 选择“流水线”类型&#xff0c;该类型的优点是定制化程度非常高 &#xff08;可选&#xff09;添加“参数化构建” 配置仓库选项(ssh连接、分支)和凭据…

一本好的电子画册应这样做,你做对了吗?

​一本好的电子画册&#xff0c;不仅要有吸引人的图文&#xff0c;还可能包括视频、音频等多媒体元素&#xff0c;为读者提供全方位的阅读体验。连贯性是指画册的整体设计风格、内容布局要协调一致&#xff0c;让读者在阅读过程中感受到流畅和自然。创新性则要求创作者在内容呈…

甲骨文(Oracle)云AI专家级证书免费获取攻略

这次分享的是甲骨文云(Oracle)2024年最新最热门的AI专家级证书&#xff0c;活动截止日期7/31。 考试为闭卷监考形式&#xff0c;但小李哥已经把题库准备好&#xff0c;分享给大家。 甲骨文Oracle☁️云计算凭借其Oracle原生产品(数据库、ERP等)在云计算市场中具有一定地位。目前…

Linux:系统引导过程与服务控制

目录 一、linux 系统引导过程 1.1、引导过程总览 1.2、系统初始化进程 &#xff08;centos 6和7 的区别&#xff09; 1.2.1、centos 6 的引导过程 init 进程 1.2.2、centos 7(systemd进程) 二、MBR、GRUB菜单、忘记密码故障修复 2.1、修复MBR扇区故障 模拟故障 重启…

代码随想录-Day41

46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; 题目描述 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成果。他需要带一些研究材料&#xff0c;但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实…

Git->git pull 和 git pull --rebase的详解

Git拉取代码的坑 格式&#xff1a;git xx指令 origin/远程仓库分支名称假如本地仓库和远程仓库都是空的 本地仓库向远程仓库提交一个文件 git commit -a -m "local first commit"&#xff1a;-a暂存修改文件到暂存区&#xff0c;准备本地提交。-m表示提交信息git pu…

2023: 芒种集•序言

2023: 芒种集•序言 2023: 芒种集•序言 从西南旅游回来&#xff0c;一直忙着整理游记“2024&#xff1a;追寻红色足迹”&#xff0c;之后又应初建平索要刘桂蓉遗作“我们一起走过”&#xff0c;于是把“别了&#xff0c;老屋”和诗作“二月”一并合编&#xff0c;把我写的悼念…

重大进展!微信支付收款码全场景接入银联网络

据中国银联6月19日消息&#xff0c;近日&#xff0c;银联网络迎来微信支付收款码场景的全面接入&#xff0c;推动条码支付互联互通取得新进展&#xff0c;为境内外广大消费者提供更多支付选择、更好支付体验。 2024年6月&#xff0c;伴随微信支付经营收款码的开放&#xff0c;微…

Chatopera 云服务实现类海尔服务智能客服的功能点比较 | Chatopera

在上一篇文章中&#xff0c;我分享了《智能客服体验分析&#xff0c;使用小程序海尔服务完成电器报修》。如果使用 Chatopera 云服务实现一个类似的应用&#xff0c;如何做呢&#xff1f;借助 Chatopera 云服务 可以实现一个智能客服&#xff0c;那么和现在的海尔服务小程序会有…

pd17虚拟机安装包:Parallels Desktop 17 激活版

Parallels Desktop 17 是一款功能强大的虚拟机软件&#xff0c;可以在 Mac 计算机上运行 Windows、Linux 和其他操作系统。使用 Parallels Desktop&#xff0c;您可以创建虚拟机并在其中安装各种操作系统&#xff0c;从而能够在同一台计算机上同时运行多个操作系统。 该软件具…

【Python datetime模块精讲】:时间旅行者的日志,精准操控日期与时间

文章目录 前言一、datetime模块简介二、常用类和方法三、date类四、time类五、datetime类六、timedelta类七、常用的函数和属性八、代码及其演示 前言 Python的datetime模块提供了日期和时间的类&#xff0c;用于处理日期和时间的算术运算。这个模块包括date、time、datetime和…

给前端小白的11个建议(少走弯路)

作为一个编程4年的的前端工程师&#xff0c;一路走来踩过许多坑。希望我的经验能让你少踩些坑&#xff0c;在编程的路上走的更顺些&#xff01; 1. 禁用var声明 只使用const或let声明变量。并且首选const&#xff0c;当一个变量需要重新赋值时&#xff0c;才使用let。并且在创…