C++?类和对象(下)!!!

news2025/7/16 4:45:43

一、前言

        在之前我们已经讨论过了有关类和对象的前置知识以及类中的六大默认成员函数,在本期我们继续再讨论类和对象中剩余的友元、初始化列表等相关知识,如果需要再了解之前的知识的话,链接奉上:C++?类和对象(中)!!!-CSDN博客、C++?类和对象(上)!!!-CSDN博客,欢迎阅读!

二、再谈构造函数

        1、初始化列表

                (1).引入

        ·        之前我们已经在构造函数部分讨论过有关初始化的内容了,我们知道,构造函数可以完成在实例化对象的同时初始化对象属性的工作了,那么为什么还要引入初始化列表的概念呢?事实上,在构造函数体内赋值不是真正的初始化,这是因为函数体内赋值可以多次赋值,但是初始化时只能初始化一次的,同时类中有以下几类成员时构造函数体内赋值是不能完成的:
                        a.引用成员变量

                        b.const成员变量

                        c.自定义类型成员(同时该类没有默认构造函数)

                观察可以发现,以上三种成员的共同点是在变量实例化的同时就必须进行初始化。

                (2).介绍初始化列表

                        (2).1.初始化列表的语法是:在构造函数名之后,以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个成员变量之后跟一个放在括号内的初始值或者表达式,如下:
                        

                        (2).2.每个成员在初始化列表只能初始化一次

                        (2).3.尽量使用初始化列表进行初始化,因为不论在函数体内是否进行赋值,成员都会先经过初始化列表,事实上,调用默认构造函数、将成员变量的缺省值初始化赋值给成员这些工作都是在初始化列表隐式进行的

                        (2).4.成员变量在类中声明的次序就是它们在初始化列表中初始化的次序,与它们在初始化列表中的位置无关,下面的代码以及运行结果可以说明这个问题:
                        代码:      

class A
 {
 public:
    A(int a)
        :_a1(a)
        ,_a2(_a1)
    {}
    
    void Print() {
        cout<<_a1<<" "<<_a2<<endl;
    }
 private:
    int _a2;
    int _a1;
 };
 
int main() {
    A aa(1);
    aa.Print();
 }

                        运行结果:
                        

                        以上运行结果就是因为先用一个随机值初始化了_a2,再用1初始化了_a1,导致最终产生以上运行结果

                        (2).5.同时在初始化列表可以初始化const类型、引用类型、没有默认构造函数的自定义类型:
                        

        2、explicit关键字

                构造函数不仅可以构造、初始化对象,对于接受单个参数的构造函数,还具有隐式类型转换的功能,接受单个参数的构造函数的都有:
                a.构造函数只有一个参数

                b.构造函数虽然有多个参数,但是除了第一个之外全都有缺省值

                c.全缺省的构造函数

                见如下代码:
                                

                可以观察到,以上代码中将2020这一int类型直接赋值给了Date类型,事实上在这个过程中,2020这一整型调用了构造函数,利用构造函数的隐式类型转换性质构造了一个临时的日期类对象,然后调用拷贝构造函数,对d完成了初始化,但是由于连续两次构造太浪费,所以编译器一般会优化掉,直接使用2020对d进行拷贝构造

                这时候如果使用explicit关键字修饰构造函数,构造函数就失去了隐式类型转换的功能,这时候就会报错。

三、static成员

        1、概念

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

        2、特性

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

                (2).静态成员变量必须在类外进行初始化,定义时不加static关键字,类中的只是声明、

                (3).类的公有静态成员可以使用类名::静态成员或者类对象.静态成员访问

                (4).静态成员函数没有隐式的this指针,不能访问非静态成员

                (5).静态成员也是成员,受访问限定符的限制

        3、应用

        下面的代码巧妙的利用了静态成员的特点,可以求出程序中共创建了多少类对象:
                

四、友元

        友元是一种突破封装的方式,可以为我们提供不少方便,但同时又因为它突破了封装,所以带来了一定的风险,不能多用。

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

        1、友元函数

                (1).引入

                我们现在要尝试重载operator<<,发现这样一个问题:我们不能将<<重载为一个成员函数,这是因为我们希望<<操作符的左操作数是ostream类型,但是由于this指针一定占用形参的第一个位置,所以只能将<<重载为全局函数,看下面的代码:
                

                可以看到在上面我们在全局重载了<<操作符,但是报了错,这是因为日期类中的成员变量都是私有的,怎么办呢?这时候就要使用我们接下来要讨论的友元函数了。

                (2).介绍

                        (2).1.友元函数可以直接访问类的私有成员,它是定义在类外的普通函数,不属于任何类,在类中声明时要加friend关键字,借用类的友元函数这一特性,我们就可以解决上面的重载<<操作符的问题了:

                        

                        可以观察到,在将<<操作符重载声明为日期类的友元函数时,没有报错,这时候,<<操作符重载就可以访问日期类的私有成员变量了

                        (2).2.友元函数不可以用const修饰,这是由于const修饰的是成员函数隐藏的this指针,友元函数只是一个普通函数,没有this指针

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

                        (2).4.一个函数可以是多个类的友元函数

                        (2).5.友元函数与普通函数的调用原理相同

        2、友元类

                友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类的非公有成员,对于友元类需要注意:
                友元关系是单向的,不具有交换性、传递性,同时也不可以继承,这一点在在以后继承的位置详细介绍

                以下的日期类Date就是时间类Time的友元类,在日期类中可以直接访问时间类中的非共有成员:
                

class Time
{
	friend class Date;
public:
	Time(int hour = 1, int minute)
		:_hour(hour),
		_minute(minute)
	{}
private:
	int _hour;
	int _minute;
};


class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void time(int hour, int minute)
	{
		_t._hour = hour;
		_t._minute = minute;
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

五、内部类

        1、概念

        如果一个类定义在另一个类内部,这个内部类就叫做外部类的内部类,内部类天然是外部类的友元类,可以在内部类中访问外部类的非公有成员,但外部类不可以访问内部类的非公有成员,外部类对于内部类没有任何特权。

        2、特性

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

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

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

六、结语

         这就是本期关于C++类和对象(下)的所有内容了,希望对大家有所帮助,感谢各位于晏、亦菲的阅读,欢迎大家和我一起讨论、进步。

        
                        

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

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

相关文章

FastAPI 零基础入门指南:10 分钟搭建高性能 API

一、为什么选择 FastAPI&#xff1f; 想象一下&#xff0c;用 Python 写 API 可以像搭积木一样简单&#xff0c;同时还能拥有媲美 Go 语言的性能&#xff0c;这个框架凭借三大核心优势迅速风靡全球&#xff1a; 开发效率提升 3 倍&#xff1a;类型注解 自动文档&#xff0c;…

机器人新革命:Pi 0.5如何让智能走进千家万户

在科技飞速发展的今天&#xff0c;机器人技术正在以一种令人惊喜的方式贴近我们的生活。最近&#xff0c;Physical Intelligence 公司推出了 Pi 0.5 版本&#xff0c;这一创新设计不仅颠覆了传统机器人的运作模式&#xff0c;更让我们看到了未来智能设备融入日常生活的无限可能…

从数据结构说起(一)

1 揭开数据结构神奇的面纱 1.1 初识数据结构 在C的标准库模板&#xff08;Standard Template Library,STL&#xff09;课程上&#xff0c;我初次结识了《数据结构》。C语言提供的标准库模板是面向对象程序设计与泛型程序设计思想相结合的典范。所谓的泛型编程就是编写不依赖于具…

Git基本使用(很详细)

一&#xff1a;Git 概述 1.1 定义&#xff1a;分布式版本控制系统 1.2 版本控制 &#xff08;1&#xff09;定义&#xff1a; 版本控制时一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统 &#xff08;2&#xff09;举例 多副本 优化&#xff1a; 不使用多…

仓颉编程语言最佳实例 “Hello, world!”

仓颉编程语言最佳实例 “Hello, world!” The Best Practice to Cangjie Programming Language - “Hello, world!” BY JACKSON 1. 仓颉集成开发工具&#xff08;IDE&#xff09;安装 打开Chrome浏览器&#xff0c;访问仓颉编程语言官网&#xff1a;https://cangjie-lang.…

[mysql]窗口函数

目录 窗口函数: 为何要学习窗口函数,与mysql5.7实现语句对比 现在我们介绍一下窗口函数: 函数规则 1序号函数 2分布函数 3前后函数 5其他函数 总结 窗口函数: 首先数据库的迁移是非常慢的,大家学习新特性的时候要考虑自己公司的数据库版本是不是和自己学习的吻合 为何…

内存四区(栈)

今天我再次学到了有趣的知识&#xff0c;内存四区&#xff01; 内存四区分为代码区&#xff0c;全局区&#xff0c;栈区&#xff0c;堆区&#xff0c;今天我们详细来讲讲栈区&#xff01; 内存四区和栈区都是用来存放数据的&#xff0c;而栈区存放的数据具体有两类 1.形参数…

新零售行业时代:如何用科技驱动传统零售的转型升级​​

新零售行业时代&#xff1a;如何用科技驱动传统零售的转型升级​​ ​​“在变化的世界中&#xff0c;唯一不变的是变化本身。”​​ ​​一、传统零售的困局&#xff1a;当“生存”成为一场鏖战​​ 街角的便利店老板老王&#xff0c;每天凌晨4点起床进货&#xff0c;却在月…

长途骑行装备攻略:VELO维乐 Angel Revo坐垫伴我畅享旅途

工作忙碌了很久&#xff0c;终于迎来了一个难得的假期。我决定和朋友一起踏上一场长途骑行之旅&#xff0c;远离城市的喧嚣&#xff0c;去寻找那份久违的宁静与自由。这次旅行&#xff0c;不仅是为了旅途风景的放松&#xff0c;更是为了体验一场身体与心灵的挑战。而朋友推荐的…

WebcamJS中文文档

文章目录 WebcamJS针对Chrome 47及以上版本的重要说明浏览器支持演示示例开源协议快速入门指南配置初始化拍摄照片自定义图像大小裁剪图像翻转图像(镜像模式)冻结/预览图像设置备用SWF文件位置重置(关闭)API 参考自定义事件向服务器提交图像跟踪上传进度包含在现有表单中自…

微软官网Win10镜像下载快速获取ISO文件

如何从微软官网轻松下载win10镜像&#xff1f;win10镜像的下载方式主要包括两种&#xff1a; 目录 一&#xff1a;借助官方工具 二&#xff1a;直接微软官网通过浏览器进行下载。 三&#xff1a;实现方法与步骤&#xff1a; 1&#xff1a;利用微软官方提供的MediaCreationT…

逆向|dy|a_bogus|1.0.1.19-fix.01

2025-04-26 请求地址:aHR0cHM6Ly93d3cuZG91eWluLmNvbS91c2VyL01TNHdMakFCQUFBQV96azV6NkoyMG1YeGt0eHBnNkkzRVRKejlyMEs3d2Y2dU9EWlhvd2ttblZWRnB0dlBPMmMwN2J0WFotcVU4V3M 个人主页的视频数据 我们需要逆向这个接口,所以现在需要分析这个请求, 分析这几个数据包可以发现: 只有…

高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!

目录 思路"情境 对象 问题"型 课题选题的类型有哪些呢&#xff1f;这要从课题题目的构成说起。通过对历年来国家社会科学基金立项项目进行分析&#xff0c;小编发现&#xff0c;课题选题类型非常丰富&#xff0c;但一般是围绕限定词、研究对象和研究问题进行不同的组…

springboot项目配置nacos,指定使用环境

遇到这样一个问题&#xff0c;在开发、测试、生成环境之间切换的问题。 大多数的操作是通过修改spring.profiles.active来确定指向使用的环境配置文件&#xff0c;对应项目中需要增加对应的配置文件。 但是现在几乎所有公司都会有代码管理不管是SVN、git&#xff0c;这样就会涉…

DIFY 浅尝 - DIFY + Ollama 添加模型

准备物料 Dify 本地部署 Ollama 下载 Open WebUI 好了现在&#xff0c;假设访问 http://localhost/apps 应该可以打开 Dify&#xff0c;设置用户登录后应该可以看到以下界面 打开 http://localhost:3000/, 你应该可以看到部署好的Open WebUI&#xff0c;并假设有下载好你感…

Java 异常处理全解析:从基础到自定义异常的实战指南

Java 异常处理全解析&#xff1a;从基础到自定义异常的实战指南 一、Java 异常体系&#xff1a;Error 与 Exception 的本质区别 1. 异常体系核心架构 Java把异常当作对象来处理&#xff0c;并定义一个基类java.lang.Throwable作为所有异常的超类。 在Java API中已经定义了许…

开源AI智能名片链动2+1模式S2B2C商城小程序源码赋能下的社交电商创业者技能跃迁与价值重构

摘要&#xff1a;在移动互联网深度重构商业生态的背景下&#xff0c;社交电商创业者面临流量成本攀升、用户粘性不足、供应链协同低效等核心痛点。本文以“开源AI智能名片链动21模式S2B2C商城小程序源码”技术体系为研究对象&#xff0c;通过分析其技术架构、商业逻辑及实战案例…

WSL 中 nvidia-smi: command not found的解决办法

前言 在使用基于 Linux 的 Windows 子系统&#xff08;WSL&#xff09;时&#xff0c;当我们执行某些操作后&#xff0c;可能会遇到输入 nvidia-smi 命令却无法被系统识别的情况。 例如&#xff0c;在终端中输入nvidia-smi 后&#xff0c;系统返回提示 -bash: nvidia-smi: co…

FPGA前瞻篇-组合逻辑电路设计-多路复用器

多路选择器&#xff08;MUX&#xff09;简介 基本概念 多路选择器&#xff08;MUX&#xff0c;Multiplexer&#xff09;是一种多输入、单输出的组合逻辑电路。 它通过选择控制信号&#xff0c;在多个输入信号中选择一个连接到输出端。 可以理解为一个多路数字开关。 &…

【Castle-X机器人】五、物联网模块配置与调试

持续更新。。。。。。。。。。。。。。。 【Castle-X机器人】五、物联网模块配置与调试 五、物联网模块配置与调试5.1 物联网模块调试物联网模块测试:控制物联网模块:物联网模块话题五、物联网模块配置与调试 5.1 物联网模块调试 调试前需确保Castle-x与mqtt主机服务器处于同…