当前位置: 首页 > news >正文

【C++】从入门到精通第三弹——友元函数与静态类成员

这里写目录标题

  • 静态类成员
  • 友元
  • 友元方法

静态类成员

类成员一般都需要通过对象来访问,不可以通过类名直接访问,但是当我们将类成员定义为静态类成员,则允许使用类名直接访问。
静态类成员是在类成员前定义static关键字。

  1 #include<iostream>2 using namespace std;3 class Cbook4 {5     public:6        static int price;7 };8 int Cbook::price = 410;9 int main()10 {11     Cbook cbook;12     cout<<"Cbook in"<<Cbook::price<<endl; //通过类名直接访问类成员13     cout<<"Cbook use"<<cbook.price<<endl;//通过对象访问静态类成员14 15 16     return 0;17 }

注意:在定义静态类成员时,通常需要在类体外部对静态类成员进行初始化。
静态类成员是被所有的类共享的,无论定义多少个类对象。类的静态类成员只有一份,同时,如果一个对象修改了静态类成员,那么其他对象的静态类成员也将改变(修改的是同一个静态类成员)

静态类成员可以是当前类的类型,其他数据类成员只能是当前类的指针或应用类型,在定义类成员时,对于静态类成员,其类型可以是当前类的类型,而非静态类·成员则不可以,除非数据成员的类型为当前类的指针或引用类型。

  8 class CBOOK9 {10     public:11         static int price;12     //    CBOOK cbook;错误,非法定义13         static CBOOK cook;14         CBOOK *cbook;15 };

静态类成员可以作为成员函数的默认参数,在定义类的成员函数时,可以为成员函数指定默认参数,其参数的默认值也可以是类的静态类成员,但是不同的数据成员不能作为成员函数的默认参数。

类的静态成员函数只能访问类的静态成员,而不能访问普通的数据成员。
而且静态类成员函数不能定义为const成员函数,如果函数的实现代码位于类体之外,则在函数的实现部分不能再标识static关键字。

友元

友元概述
友元是使用friend关键字, 让特定的函数或者别的类的所有成员函数对私有数据成员进行读写。
好处是:可以保持数据的私有性,又可以让特定的类或者函数直接访问私有成员。
为了提升效率,友元可以让普通函数直接访问一个类的保护或私有数据成员,但是如果没有友元机制,就只能将类的数据成员声明为公共的,从而任何函数都可以无约束地访问它。
友元函数:

1 #include<iostream>2 using namespace std;3 class Friendfunction4 {   5     public:6         Friendfunction()7         {8             m_height = 0;9             m_width = 0;10         }11         Friendfunction(int height,int width)12         {13          m_width = width;14          m_height = height;15         }16         int getHeight()17         {18             return m_height;19         }20         int getWidth()21         {22             return m_width;23         }24         friend int friendfunction(Friendfunction &myret);25         protected:26         int m_height;27         int m_width;28 };29 int friendfunction(Friendfunction &myret)30 {31     return myret.m_height*myret.m_width;32 }33 int main()34 {35     Friendfunction ff(120,210);36     cout<<"result = "<<friendfunction(ff)<<endl;37 38     return 0;39 }

在函数friendfunction中可以直接使用Friendfunction类对象中的数据成员,就是因为第24行代码的作用:

 24         friend int friendfunction(Friendfunction &myret);

此例子既很好的保护隐藏了数据,又可以使外界的特定函数直接访问这些隐藏数据。

接下来介绍友元类
就如下面第14行代码所示 : friend class Clist; 就可以声明友元类啦。用法和功能与友元函数用法功能类似。这里就不再详细赘述了,直接看代码:

  1 #include<iostream>2 #include<string>3 using namespace std;4 class Cltem5 {6     private:7         string m_name;8         void outputname()9         {10             cout<<"name = "<<m_name<<endl;11             12         }13     public:14        friend class Clist;15         void setltemname(string name)16         {17            m_name= name;18         }  19 };      20 class Clist21 {22     private:23         Cltem m_ltem;24     public:25         void outoutltem();26 };27 void Clist::outoutltem()28 {29     m_ltem.setltemname("beijing");30     m_ltem.outputname();31 }32 int main()33 {34     Clist list;35     list.outoutltem();36 37     return 0;38 }

定义Cltem类时,使用了friend关键字将Clist类定义为Cltem类 的友元,这样一来,Clist类中的所有方法都可以访问Cltem类中的私有成员了。

友元方法

在我们真正开发程序时,有时候需要控制一个类对当前类的私有成员的发法。比如,我们需要实现只允许Cbook类中的某个成员来访问·Clibrary类的私有成员,而不允许其他成员函数访问Clibrary类的私有数据,这可以通过定义友元函数来实现。在定义Clibrary类的时候,可以将Cbook类的某个方法定义为友元方法,这样就限制了只有该方法允许访问Clibrary类的私有成员。

1 #include<iostream>2 using namespace std;3 class Clibrary;4 class Cbook5 {6     public:7         Cbook();8         ~Cbook();9         Clibrary *position;10         void putcbook(); //声明友元11         //void notfriendcbook();//不声明友元,作为对比12 };13 class Clibrary14 {15     friend void Cbook::putcbook();16     private:17     string name;18     void putname()19     {20         cout<<"name = "<<name<<endl;21     }22     public:23     void setname(string name);24 };25 void Clibrary::setname(string name)
26 {   27     this->name = name;28 }29 void Cbook::putcbook()30 {   31     position->setname("beijing");32     position->putname();33 }  /*34 void Cbook::notfriendcbook()35 {36     position->setname("beijing");37     position->putname();38 }*/39 Cbook::Cbook()40 {41     position = new Clibrary();42 }43 Cbook::~Cbook()44 {45     delete position;46    position = NULL;47 }48 49 int main()50 {51     Cbook cook;52     cook.putcbook();53 54    // cook.notfriendcbook();55     return 0;56 }

就像上面代码所示,如果把没有声明友元的成员函数放开,就会出现下面这样的错误。

[bsk@localhost c++]$ g++ friendmethod.cpp 
friendmethod.cpp: In member function ‘void Cbook::notfriendcbook()’:
friendmethod.cpp:18:10: error: ‘void Clibrary::putname()’ is privatevoid putname()^
friendmethod.cpp:37:23: error: within this contextposition->putname();

原因也很简单,就是因为notfriendcbook()成员函数不是Clibrary类的友元,所以这个成员函数就不能访问去访问Clibrary类中的私有属性。
此外,全局函数也可以作为类友元,一样可以访问类中的私有成员。

最后简单来谈一下
友元函数在访问类对象中的成员时,不需要通过对象名。友元函数没有this指针,如果不通过对象名就无法找到类对象中的非static成员,也就无法访问。但是当访问类对象中的static成员时,就可以不用通过对象名访问。

相关文章:

【C++】从入门到精通第三弹——友元函数与静态类成员

这里写目录标题 静态类成员友元友元方法 静态类成员 类成员一般都需要通过对象来访问&#xff0c;不可以通过类名直接访问&#xff0c;但是当我们将类成员定义为静态类成员&#xff0c;则允许使用类名直接访问。 静态类成员是在类成员前定义static关键字。 1 #include<iost…...

acwing算法基础之搜索与图论--floyd算法

目录 1 基础知识2 模板3 工程化 1 基础知识 floyd算法的时间复杂度为O(n^3)&#xff0c;它用来解决多源最短路问题。它的原理是基于动态规划。 floyd算法的关键步骤&#xff1a; k从1到n。i从1到n。j从1到n&#xff0c;d[i][j] min(d[i][j], d[i][k] d[k][j])。经过上述三…...

Zabbix监控SSL证书有效期

一、介绍 由于业务需要&#xff0c;最近通过 Let’s Encrypt 申请了一些 SSL 证书&#xff0c;而证书有效期为 3 个月&#xff0c;需要在证书到期之前 renew。由于域名较多经常忘记 renew&#xff0c;导致证书过期&#xff0c;因此想通过 Zabbix 的方式监控证书的到期时间&…...

Arduino OneButton按键处理库实现单击/双击/长按功能

Arduino OneButton按键处理库实现单击/双击长按功能 ✨在Arduino开发平台下&#xff0c;按键的单击/双击/长按功能&#xff0c;在通过使用OneButton库&#xff0c;很容易就可以轻松实现。这就是支持C/C模块化设计的好处&#xff0c;避免重复性开发的工作。 &#x1f516;本文将…...

day52 django的下载与安装

课程的大致安排 大概两周的时间都是围绕着Django框架的学习&#xff0c;包括后续要学习的drf、Redis、celery、es等技术栈都是围绕Django展开的&#xff0c;因此、要求所有的同学必须认证学习了 市场中所有使用Python开发的web项目&#xff0c;Django框架占有率达到90%以上 …...

WebGL智慧城市软件项目

WebGL开发智慧城市项目时&#xff0c;需要考虑多个方面&#xff0c;包括技术、隐私、安全和可持续性。以下是一些需要注意的关键问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.隐私和数据安全…...

VMware重装后没有虚拟网卡

我重装VMware之后网络适配器里面没有虚拟网卡&#xff0c;找了CSDN上很多博主说的&#xff0c;都没用。 最终去看了b站的up视频就成功了。 原因是因为第一次安装后卸载不干净&#xff0c;软件在电脑上的注册表没有删掉。 要用下面两个软件清理一下残留文件&#xff0c;这两个…...

软件安全基础

传参基础 64位汇编传参&#xff0c;当参数少于7个时&#xff0c; 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。 当参数为7个以上时&#xff0c; 前 6 个与前面一样&#xff0c; 但后面的依次从 “右向左” 放入栈中&#xff0c;即和32位汇编一样。 我们这边要利用wr…...

探索项目管理软件的多重用途和益处

项目管理软件俨然成了当下项目管理话题中的热门词条&#xff0c;作为一个辅助性管理工具&#xff0c;项目管理软件有什么用&#xff1f;真的值得购入吗&#xff1f; 什么是项目管理软件 顾名思义&#xff0c;项目管理软件就是指在项目管理过程使用的各种软件工具。项目管理软件…...

Arduino ESP8266使用AliyunIoTSDK.h连接阿里云物联网平台

文章目录 1、AliyunIoTSDK简介2、相关库安装3、阿里云创建产品&#xff0c;订阅发布4、对开源的Arduino ESP8266源代码修改5、使用阿里云点亮一个LED灯6、设备向阿里云上传温度数据7、项目源码 1、AliyunIoTSDK简介 AliyunIoTSDK是arduino的一个库&#xff0c;可以在arduino的…...

【车载开发系列】AutoSar中的CANTP

【车载开发系列】AutoSar中的CANTP 【车载开发系列】AutoSar中的CANTP 【车载开发系列】AutoSar中的CANTP一. CANTP相关术语二. CANTP相关概念1&#xff09;单帧&#xff1a;SF(Single Frame)2&#xff09;首帧&#xff1a;FF(First Frame)3&#xff09;连续帧CF(Consecutive F…...

JUL日志

文章目录 JUL日志JUL日志讲解Properties配置文件编写日志配置文件Lombok快速开启日志Mybatis日志系统 JUL日志 如果使用System.out.println来打印信息&#xff0c;项目中存在大量的控制台输出语句&#xff0c;会显得很凌乱&#xff0c;而且日志的粒度是不够细的&#xff0c;假…...

ZZ308 物联网应用与服务赛题第G套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 &#xff08;G卷&#xff09; 赛位号&#xff1a;______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等&#xff1b; 2.竞赛任务中所使用…...

如何使用 vcpkg 编译Google-V8脚本引擎(ECMA/JavaScript)?

WIN32K下一键杀死所有同名进程命令行&#xff1a;taskkill /F /IM chrome.exe ############################## 1、准备 Visual Studio 2019 2、准备 Visual Studio 2022 3、安装 VC、MSBuild 编译集成环境 4、安装 Python 3.x&#xff0c;早期V8发行版本编译安装 2.x 5、…...

系列二十二、idea Live Templates

一、idea Live Templates 1.1、Java Group 1.1.1、fast fast 快速在类上添加注解Data AllArgsConstructor NoArgsConstructor Accessors(chain true) ToString(callSuper true) 1.1.2、getThreadName getThreadName快速获取当前线程的名字Thread.currentThread().getName…...

电脑本地安装宝塔/docker 安装宝塔

一、先去docker官网(http://docker.com)下载软件并进行安装&#xff0c;网站打不开多试几次或者找梯子。 二、macos系统里按“command 空格”搜索“终端”回车&#xff0c;启动终端程序。 三、执行下面命令&#xff0c;拉取docker镜像。 docker pull pch18/baota:clear pch…...

Java Lambda 表达式笔记

文章目录 Java Lambda 表达式语法Lambda 表达式实例Lambda表达式与函数式接口方法引用处理lambda表达式的接口 Java Lambda 表达式语法Lambda 表达式实例Lambda表达式与函数式接口方法引用处理lambda表达式的接口 Java Lambda 表达式 Lambda 表达式&#xff0c;也可称为闭包. …...

Flutter笔记:状态提升、控制器模式、GetX控制器和服务

Flutter笔记 状态提升、控制器模式、GetX控制器和服务 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/1…...

9.spark自适应查询-AQE之动态调整Join策略

目录 概述动态调整Join策略原理实战 动态优化倾斜的 Join原理实战 概述 broadcast hash join 类似于 Spark 共享变量中的广播变量&#xff0c;Spark join 如果能采取这种策略&#xff0c;那join 的性能是最好的 自适应查询AQE(Adaptive Query Execution) 动态调整Join策略 原…...

CentOs7 NAT模式连接网络

1.配置动态网络 1.1 检查主机网卡配置 检查主机的网络设置 进入控制面板&#xff0c;找到网络共享中心 查看适配器是否都已经开启 1.2 设置虚拟机的网络配置 打开虚拟机网络配置设置&#xff0c;对网卡VMnet8 进行设置 记住网关 全部选择应用&#xff0c;确定 1.3 设置…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...