【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类

标题:【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类

@水墨不写bug


(图片来源于网络)


目录

(一)静态成员

(二)友元

 (三)内部类

(四)深入理解类和对象、总结


正文开始: 

(一)静态成员

        C语言中有静态的概念,比如静态函数和静态变量。

静态变量:存储在静态区,随着主函数的开始而创建并初始化,随着程序结束而销毁。选择创建静态变量,会使变量的生命周期延长到程序结束。

静态函数则是不同的概念:静态函数只能在当前源文件中访问,不能被其他源文件访问调用。选择定义静态函数的作用是将函数的作用域限制在当前源文件内,并且可以避免与其他源文件中定义的同名函数发生冲突。

        Cpp中,由于新增了类和对象的特性,对静态变量的处理就有所不同了。

         类中是可以创建静态变量的,由于静态变量存储在静态区,只初始化一次,所以一个类(Class)内部(定义)包含有的静态变量是可以通过任意一个这个Class创建的对象来访问的,这也就表明了这个静态变量是属于这个类的,而不是单独属于某个实例化的对象。

        如果我们执行下面这一段代码:

#include<cstdlib>
#include<iostream>
using namespace std;
class A
{public:private:static int _a;int _b;int _c;
};
int main()
{A aa;cout << sizeof(aa) << endl;return 0;
}

 结果可能会让你惊讶:静态对象_a不是存储在对象aa中的!

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

(类的成员函数指针也不存放在类内,而是存放在公共的代码段)

 其次,类静态对象的定义是在类外部的。

class A
{
public:private:static int _a;int _b;int _c;
};int A::_a = 5;

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

         访问方式:

        类静态成员对象有两种访问方式:

        1)通过实例化的对象访问;

    A aa;//实例化一个对象aa._a++;//通过对象访问

        2)通过类名访问;

    A::_a++;//直接通过类名访问

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

>同时就是说:静态成员函数只可以访问静态变量

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


(二)友元

        友元是通过一个关键字(friend)来实现的;我们在实现一个类的时候,通常把成员函数定义为共有(public),而把成员变量定义为私有(private)。

        如果我们在项目中想要通过重载cout来输出自己的自定义类型对象时,一定会遇到这样的问题:


ostream& operator<<(const Date d) 
{out << this->_year << " " << this->_month << " " << this->_day;out << endl;return out;
}

        由于用类对象调用重载后的函数时,参数的顺序首先是this,其次是其他的对象。所以调用重载后的cout会十分的别扭,而与常规的逻辑不同:

    cout<<d1;

         解决方法就是第一个参数必须是cout,其次是其他参数。由于类内部定义的函数的第一个参数必是this指针,所以这个逻辑正确的函数必须在类外定义。

        但是由于类外的函数不能访问类的private的成员函数,所以为了解决这一问题,Cpp就引入“友元”的概念:

        成为友元的函数可以突破private的限制,直接访问类的私有成员变量。

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

 注意:

        1)友元提供了一种突破封装的方式,有时提供了便利;

        2)但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

        通过定义友元函数,我们可以写出逻辑正确的cout重载函数:

ostream& operator<<(ostream& out, const Date d) 
{out << d._year << " " << d._month << " " << d._day;out << endl;return out;
}

 函数的效果:


 (三)内部类

        什么是内部类?如果一个类,它定义在另一个类的内部,那么这个定义在内部的类就称为“内部类”。

示例:

class A
{class B{int _c;    };
};

此时,B就是A的内部类。 

内部类也是一个类,只不过他被A的作用域又封装了一层,想要找到B,则要:

//创建一个类B,需要在A的作用域中去寻找A::B aa;

 内部类是一个独立的类,它是外部类A的友元类:        

        内部类B可以访问A的私有成员,而A不能访问B的私有成员。

        (内部可以访问外部,而不能反着来)

 其他特性:
        1. 内部类可以定义在外部类的public、protected、private都是可以的。
        2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
        3. sizeof(外部类)=外部类,和内部类没有任何关系。

(四)深入理解类和对象、总结

        假如将来你要开一家外卖公司,需要打造你的项目,这时你该如何保存信息?

        创建多个类:外卖骑手,商家,顾客类;

每个类包含的信息(包含的成员变量),拥有的功能(实现的函数)都是最必要的:

骑手:姓名,电话,实时位置信息等;

商家:店名,位置,菜品,价格信息等;

顾客:姓名,电话,住址信息等;

        这些成员变量就是根据实际需求来定义的。对于这些类,他们之间也会有交互,需要实现交互函数,这就是后话了。


        类和对象是一种能够将现实生活中的关系相对较好的表现出来,这也是面向对象编程的实际需求。

        与此同时,现实生活中的实体计算机并不认识现实生活中的对象,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。

考虑显示需求:

        对于商家,他们都有一个特征:他们是卖东西的,需要客户。

        对于骑手,他们的特征是:他们是接单送单的,需要商家的订单。

        对于顾客,他们的特征是:他们是需要产品的,要在商家那里消费的,需要商家。

        据此,我们可以把所有的商家抽象为一类,创建一个商家类;把所有的骑手抽象为一个类,创建一个骑手类;把所有的顾客抽象为一个类,创建一个顾客类。

        类是对象的抽象,对象是类的实际体现。

        类的属性和功能来源于生活中的实际需要。


 

用一张图总结:

 


完~

未经作者同意禁止转载 

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

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

相关文章

生产性服务业与生活性服务业如何区分

服务业的兴旺发达是现代经济的显著特征&#xff0c;是经济社会发展的必然趋势&#xff0c;是衡量经济发展现代化、国际化、高端化的重要标志。生产性服务业和生活性服务业是服务业的重要组成部分&#xff0c;是当前中国经济最具活力的产业&#xff0c;也是未来经济发展最具潜力…

有哪些好用的3dMax大神插件?

有哪些好用的3dMax大神插件&#xff1f; Mesh Insert 3DMAX网格插入插件Mesh Insert&#xff0c;在选择的面上安门窗、打螺丝、挖洞、插入眼耳口鼻及其它网格模型等可以分分钟搞定&#xff01;它通过将面选择替换为库中的资源来加快建模过程。非常适合硬网格和有机建模&#xf…

iOS ------ 多线程基础

一&#xff0c;进程和线程 1&#xff0c;进程 定义&#xff1a; 进程是指在系统中正在运行的一个应用程序每个进程之间是独立的&#xff0c;每个进程均运行在其专有的且受保护的内存进程是系统进行资源分配和调度的一个独立单位 补充&#xff1a;iOS系统是相对封闭的系统&a…

服务网格 SolarMesh v1.13 重磅发布

SolarMesh是行云创新推出的流量治理平台&#xff0c;它基于Istio&#xff0c;为部署在K8s集群上的应用提供全面的流量治理能力。 在之前的版本中&#xff0c;SolarMesh提供的能力有&#xff1a;流量视图&#xff0c;流量控制策略批量配置&#xff0c;API级别的流量数据采集和展…

【上海大学计算机组成原理实验报告】五、机器语言程序实验

一、实验目的 理解计算机执行程序的实际过程。 学习编制机器语言简单程序的方法。 二、实验原理 根据实验指导书的相关内容&#xff0c;指令的形式化表示是指采用一种规范化的符号系统&#xff0c;以更清晰、精确地描述和表示指令的逻辑功能和操作步骤。 汇编是一种编程语言…

MM模块学习二 (供应商,物料后台相关配置)

公司代码配置 新建条目&#xff08;只是建了一个名字出来&#xff0c;后面很多表都是没有得&#xff09; 接下来定义公司代码&#xff1a; 公司代码复制完成&#xff08;后续修改交给财务顾问去做&#xff09; 复制工厂&#xff1a; 复制工厂完成&#xff1a; 修改复制过去的工…

Linux服务器lvm磁盘管理fdisk和df磁盘大小不同修改

服务器端由于硬盘是通过VCenter原来100G磁盘复制的虚拟机,复制完成后,原来100G的磁盘通过选择 磁盘重新复制出150G的磁盘,开机后发现还是原来的100G的磁盘,通过fdisk -l 查看有个sdb是150G, 但是已经划转的lvm盘只有100G, 通过df查看也是原来的100G: pvs查看pv里也是10…

用c++实现快速排序、最大子段和问题

6.2.2 快速排序 【问题】快速排序(quick sort)的分治策略如下&#xff08;图6-5)。 (1)划分&#xff1a;&#xff08;选定一个记录作为轴值&#xff0c;以轴值为基准将整个序列划分为两个子序列&#xff0c;轴值的位置在划分的过程中确定&#xff0c;并且左侧子序列的所有记录…

26 分钟惊讶世界,GPT-4o 引领未来人机交互

前言 原文链接&#xff1a;OpenAI最新模型——GPT-4o&#xff0c;实时语音视频交互&#xff0c;未来人机交互近在眼前 - Kaiho小站 北京时间 5 月 14 日凌晨&#xff0c;OpenAI 发布新一代模型——GPT-4o&#xff0c;仅在 ChatGPT 面世 17 个月后&#xff0c;OpenAI 再次通过…

【EasyX】快速入门——静态图形篇

1.基本说明 EasyX 是针对 C 的图形库&#xff0c;可以帮助 C/C 初学者快速上手图形和游戏编程。 比如&#xff0c;可以基于 EasyX 图形库很快的用几何图形画一个房子&#xff0c;或者一辆移动的小车&#xff0c;可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏&#xff0c;可以练…

使用VMware或VirtualBox安装eNSP Pro并使用CRT连接设备

文章目录 使用Oracle Virtual Box安装eNSP Pro创建虚拟机配置网卡配置带外管理网络 使用VMware Workstation安装eNSP Pro转换文件格式及虚拟磁盘模式配置网卡创建虚拟机配置使用CRT连接管理设备 前一段时间是开放了eNSP Pro的账号权限&#xff0c;但是在写博客时&#xff0c;权…

27.哀家要长脑子了!

目录 1.316. 去除重复字母 - 力扣&#xff08;LeetCode&#xff09; 2. 1209. 删除字符串中的所有相邻重复项 II - 力扣&#xff08;LeetCode 哎哟 烦死了 刚刚不小心退出又没保存 又要写一遍 烦死了 最近刷题不得劲啊 感觉这脑子没长一点 1.316. 去除重复字母 - 力扣&am…

(实测验证)【移远EC800M-CN 】GNSS功能打开和关闭关闭步骤验证

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 一、打开GNSS功能 步骤一、通过 ATQGPSCFG 配置 GNSS 参数 &#xff08;1&#xff09;该命令用于查询和配置 GNSS 不同的设置&#xff0c;包括 NMEA 语句输出端口、NMEA 语句的输出类型等。 1.1…

NSSCTF | [SWPUCTF 2021 新生赛]easyupload2.0

先传一个普通的一句话木马试一试 GIF89a <?php eval($_POST[shell]);?> 可以看到回显&#xff0c;不允许上传php文件。 使用Burpsuite抓包只修改ContentType后发现也不能绕过&#xff0c;说明服务器使用了黑名单后缀限制&#xff0c;那么我们可以使用其他的后缀代替ph…

电路板维修【四】

【开关电源输出电压偏低不稳&#xff0c;用示波器立马锁定故障范围】&#xff1a;https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏&#xff1a; 电源芯片的供电电压来回跳变&#xf…

基于卷积神经网络CNN,使用二维卷积Conv2D实现MNIST数字识别的四种方法

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

ROS 2边学边练(48)-- 将URDF与robot_state_publisher一起使用

前言 本篇将完成一个行走的机器人&#xff0c;并以tf2消息的方式实时发布机器人状态&#xff0c;以便我们在Rviz中同步查看。 首先&#xff0c;我们创建描述机器人装配的URDF模型。接下来&#xff0c;我们编写一个节点&#xff0c;用于模拟运动并发布JointState和位姿变换。然后…

醉了,面个功能测试,还问我Python装饰器

Python 装饰器是个强大的工具&#xff0c;可帮你生成整洁、可重用和可维护的代码。某种意义上说&#xff0c;会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器&#xff0c;你可以将它们视为将函数作为输入并在不改变其主要用途的情况下扩展其功能的函数。装饰器可…

dhcp(接口和全局地址池模式)

接口地址池和全局地址池 dhcp应用 1.全部开启dhcp功能 2.ar5 0口接口地址池 1口全局地址池 3.ar6和ar7配置&#xff0c;查看能否自动获取ip 左右不同两个网络&#xff0c;接口和全局地址池的区别 部分截图 ar6 ar7 ar5

(实测验证)【移远EC800M-CN 】TCP 透传

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 1、配置移远EC800M-CN TCP 透传 串口助手发送&#xff1a; ATQIOPEN1,0,"TCP","36.137.226.30",39755,0,2 //配置服务器地址和端口号&#xff1b; 4G模组返回…