【C++】类和对象(7)--友元, static成员

目录

一 友元

1 友元概念

2 友元函数

3 友元类 

二 static成员

1 概念

2 用法

3 static成员特性

4 例题


一 友元

1 友元概念

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以 友元不宜多用。

友元分为:友元函数和友元类

2 友元函数

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在 类的内部声明,声明时需要加friend关键字。

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}int main()
{Date d;cin >> d;cout << d << endl;return 0;
}

说明:

1 友元函数可访问类的私有和保护成员,但不是类的成员函数

2 友元函数不能用const修饰

3 友元函数可以在类定义的任何地方声明,不受类访问限定符限制

4 一个函数可以是多个类的友元函数

5 友元函数的调用与普通函数的调用原理相同

3 友元类 

1 友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

2 友元关系是单向的,不具有交换性。

3 比如Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

4 友元关系不能传递

如果C是B的友元, B是A的友元,则不能说明C时A的友元。

友元关系不能继承,在继承位置再详细介绍。

class A
{
private:int h;
public:// A和B关系// B就是一个普通类,只是受A的类域和访问限定符限制,本质相当于被封装了一下// B天生就是A的友元class B {public:void func(){A aa;// B天生就是A的友元aa.h++;}private:int _b;};
};int main()
{cout << sizeof(A) << endl;A aa;A::B bb;return 0;
}

输出: 4

说明:

1. 内部类可以定义在外部类的public、protected、private都是可以的。

2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

3. sizeof(外部类)=外部类,和内部类没有任何关系

二 static成员

1 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用 static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

2 用法

实现一个类,计算程序中创建出了多少个类对象。

class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() {}// _scount属于私有 在外面访问不了 所以创建一个成员函数来获取int GetCount(){return _scount;}
private://类里声明static int _scount;//属于整个类 属于这个类的所有对象 每次调用_scount的时候都会调用同一个_scount
};//类外定义
int A::_scount = 0;void func()
{A aa;A bb;
}void TestA()
{func();//没有创建对象 调用不了成员函数//方法1 A cc;//有名对象cout << cc.GetCount() - 1 << endl;//为了调用而创建的,所以要-1//方法2// A() 这种写法叫做匿名对象,生命周期只在这一行cout << A().GetCount() - 1 << endl;
}int main()
{TestA();return 0;
}

优化:

class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() {}// _scount属于私有 在外面访问不了 所以创建一个成员函数来获取static int GetCount(){return _scount;}
private://类里声明static int _scount;//属于整个类 属于这个类的所有对象 每次调用_scount的时候都会调用同一个_scount
};//类外定义
int A::_scount = 0;void func()
{A aa;A bb;
}void TestA()
{func();cout << A::GetCount()<< endl;
}int main()
{TestA();return 0;
}

输出: 2

这是为啥?

静态成员函数没有隐藏的this指针 所以不用创建对象

3 static成员特性

1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

静态成员函数可以调用非静态成员函数吗?-->错误 静态成员函数没有this指针 (也不能访问非静态成员变量)

非静态成员函数可以调用类的静态成员函数吗?-->正确

4 例题

求1+2+3+...+n_牛客题霸_牛客网

 

class Sum
{
public:Sum(){_ret += _i;++_i;}static int GetRet(){return _ret;}
private:static int _i;static int _ret;
};int Sum::_i = 1;
int Sum::_ret = 0;class Solution {
public:int Sum_Solution(int n) {Sum arr[n];return Sum::GetRet();}
};

本节算是一个补充吧 一些细节上的说明  内容简单, 不难理解, 但是这些特性谨记为好

继续加油!

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

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

相关文章

2023年高压电工证考试题库及高压电工试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年高压电工证考试题库及高压电工试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的高压…

风火编程--playwright爬虫

playwright爬虫基本用法 等待加载 page.wait_for_load_state(‘networkidle’) text page.content() 点击 demo with sync_playwright() as pw:browser pw.chromium.launch(headlessTrue)context browser.new_context()page context.new_page()page.goto(url)page.wait…

大数据架构

大数据架构 https://huaweicloud.csdn.net/633578fed3efff3090b58398.html https://blog.csdn.net/yuanziok/article/details/117030031 https://blog.csdn.net/qq_46675545/article/details/121985987 https://blog.csdn.net/qq_33367934/article/details/127685417 https://b…

JAXB实现XML和Bean相互转换

目录 XML和Bean转换工具简介JAXB简介Java Bean类XMLUtil工具类 另一篇转换方式 xstream实现xml和java bean 互相转换 XML和Bean转换工具简介 Java中实现XML和Bean的转换的方式或插件有以下几种&#xff1a; JAXB&#xff08;Java Architecture for XML Binding&#xff09;&…

C#中.NET 6.0 控制台应用通过EF访问新建数据库

目录 一、 操作步骤 二、编写EF模型和数据库上下文 三、 移植&#xff08;Migrations&#xff09;数据库 四、编写应用程序并运行 前文已经说过.NET Framework4.8 控制台应用通过EF访问新建数据库&#xff0c;这里的数据据库要根据事先编写好的EF模型、经过一番操作&#x…

【碰碰球】弹珠游戏-微信小程序项目开发流程详解

还记得小时候玩过的弹珠撞击游戏不&#xff0c;这里把它的实现原理通俗易懂地讲一下&#xff0c;看看怎样实现一个碰碰球(弹珠)小游戏&#xff0c;除了个人玩法&#xff0c;也可以双人玩哦&#xff0c;与打乒乓球一样的&#xff0c;可练习临场反应。 创建项目 打开微信开发者…

前端面试:如何实现并发请求数量控制?

题目&#xff1a;实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下&#xff1a; 要求最大并发数 maxNum;每当有一个请求返回&#xff0c;就留下一个空位&#xff0c;可以增加新的请求;所有请求完成后&#xff0c;结果按照 urls 里面的顺序依次打出&#xff1b;…

DE算法简介

文章目录 前言一、DE是什么&#xff1f;二、DE流程2.1 初始化种群2.2 变异&#xff08;差分操作&#xff09;2.3 交叉2.4 选择2.5 重复迭代 三、DE运行结果 前言 这两天看了DE算法&#xff0c;简单说下自己的认识 一、DE是什么&#xff1f; 百科定义&#xff1a;差分进化算…

C++sqrt函数题目

判断完全平方数 #include<bits/stdc.h> using namespace std; int n;int main() {cin>>n;if(sqrt(n)n/sqrt(n)&&sqrt(n)/1sqrt(n)){cout<<"yes";}else cout<<"no";return 0; } 输出所有因数 #include<bits/stdc.h> …

vivado产生报告阅读分析10-时序报告6

1、“ Timing Summary Report ”详情 “ Bus Skew Report ” &#xff08; 总线偏差报告 &#xff09; 包含下列部分 &#xff1a; • “ General Information ”部分 • “ Summary ”部分 • “ Set Bus Skew ”部分 “ General Information ”部分 “ Timing Summa…

Python OpenCV调整图像亮度对比度及RGB色彩

python通过opencv库调整图像的步骤&#xff1a; 1. 读取图像 直接通过cv2库读取图像&#xff0c;可以读取jpg, png等格式 import cv2 import numpy as npimage cv2.imread(C:\\D\\temp\\205250_last.png) 2. 调整图像亮度及对比度 OpenCV提供 convertScaleAbs 函数来调整…

Vue+ElementUI技巧分享:自定义表单项label的文字提示

文章目录 概要在表单项label后添加文字提示1. 使用 Slot 自定义 Label2. 添加问号图标与提示信息 slot的作用详解1. 基本用法2. 具名插槽 显示多行文字提示的方法1. 问题背景2. 实现多行内容显示3. 样式优化 结语 概要 在Vue和ElementUI的丰富组件库中&#xff0c;定制化表单是…

Linux进程间通信之匿名管道

文章目录 为什么要有进程间通信pipe函数共享管道原理管道特点管道的四种情况 管道的应用场景&#xff08;进程池&#xff09;ProcessPool.ccTask.hpp 为什么要有进程间通信 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享…

Vue3-自定义hook函数

Vue3-自定义hook函数 功能&#xff1a;可以将组合式API封装成一个函数&#xff0c;用于解决代码复用的问题。注意&#xff1a;需要在src文件夹下创建一个文件夹hooks&#xff0c;在里面放js文件&#xff0c;命名随意&#xff0c;主要是将setup函数中的代码放入js文件中。 // s…

岁月

《岁月》 作者&#xff0f;罗光记 岁月如梭逝不停&#xff0c; 往事如烟散无影。 青春已去心犹在&#xff0c; 笑看人生淡如菊。

Qt的日志输出

在Qt中&#xff0c;一般习惯使用qDebug信息进行输出和打印调试信息到console或者文件中&#xff0c;在qDebug中&#xff0c;也有一些小技巧&#xff0c;可以帮助我们更好的使用qDebug打印日志记录&#xff0c;本文分享了qDebug使用的一些小技巧。 1. 打印出文件名、行号、调用函…

Windows10下Maven3.9.5安装教程

文章目录 1.下载maven2.安装3.配置系统变量3.1.新建系统变量 MAVEN_HOME3.2.编辑系统变量Path 4.CMD命令测试是否安装成功5.配置maven本地仓库6.配置国内镜像仓库 1.下载maven 官网 https://maven.apache.org/download.cgi 点击下载。 2.安装 解压到指定目录 D:\installSoft…

计算机硬件的基本组成

一、冯诺依曼结构 存储程序&#xff1a; “存储程序”的概念是指将指令以二进制代码的形式事先输入计算机的主存储器&#xff0c;然后按其在存储器中的首地址执行程序的第一条指令&#xff0c;以后就按该程序的规定顺序执行其他指令&#xff0c;直至程序执行结束。 冯诺依曼计…

io多路复用:select、poll和epoll

1、为什么使用多路复用&#xff1a; 1.1单线程BIO监听socket 多路复用一般用于网络io当中&#xff0c;提到网络io我们肯定能想到socket。如果我们想要一个线程单纯的用向下文的方式监听很多个socket看他是否有事件发生&#xff0c;那这样是不可行。 但上一个socket1没有可读事…

Codewhisperer 使用评价

最近亚⻢逊推出了一款基于机器学习的 AI 编程助手 Amazon CodeWhisperer&#xff0c;可以实时提供代码建议。在编写代码时&#xff0c;它会自动根据现有的代码和注释给出建议。Amazon CodeWhisperer 与GitHub Copilot类似&#xff0c;主要的功能有: 代码补全注释和文档补全代码…