类和对象——相关的零碎知识
前提提示:
其实C++中的类和对象,最重要的是6个默认函数,如有忘记,请移步到:类和对象。本章是对于一些细节知识的补充和拓展。
1. 隐示类型转换
在运算时,运算符左右两边的操作数的类型不同,编译器是会按照类型转换的要求,将两个操作数的类型转换为一样,然后就行运算。
1.1 内置类型的隐示类型转换
我们的内置类型,他们之间出现类型不一致的情况时,是有一套类型转换的规则的,但是还有自定义类型,内置类型和自定义类型之间是如何转化?
答:这个其实和我们的前面将的构造函数有关了,其实在类型转换的时候,我们可以很容易的发现,被类型转化的变量其实没有改变,但是确确实实有实现了运算,就是因为隐示类型转换的时候,产生了临时变量,临时变量存储着变量类型转换之后的结果。
#include<iostream>
using namespace std;int main()
{double b = 1.223;int a = b;cout << a << " " << b << endl;return 0;
}

程序的执行逻辑:

这串代码实际上就是可以反映出,在隐示类型转换时,产生了临时变量。如果不产生临时变量,那么输出的结果是:1 1,但输出的结果是1 1.223 ,就说明产生了临时变量。
1.2 自定义类型的隐示类型转换
解释:这里的自定义类型的隐示类型转换,是指内置类型想自定义类型转换,自定义类型是无法想内置类型转换的。同时不同的自定义类型之间也是不能互相类型转换的。
#include<iostream>
using namespace std;class A
{
public://构造函数A(int a): x(a),y(a){cout << "A(int a)" << endl;};void operator=(A&a){x = a.x;y = a.y;cout << "void operator=(A&a)" << endl;}private:int x;int y;
};int main()
{int a = 6;A tmp = a;return 0;
}
上述程序中的两个变量 a和tmp的类型不相同,那他们是怎么进行隐示类型转换的呢?这个就需要和之前的初始化列表联系起来了,因为这个转换需要使用到类的6个默认函数中的连续构造函数和拷贝构造,程序的执行逻辑如下。

程序输出的结果:

为什么上面讲的是先连续构造然后拷贝构造,为什么程序在执行的时候只进行了普通的构造?这是因为编译器的优化。编译器将连续构造+拷贝构造优化为直接构造,这样更加的节省空间和时间。但是我们也发现其实这样的隐示类型转换时十分依赖于构造函数的书写的。
当将构造函数修改为如下:
class A
{
public://构造函数A(int a=0,int b=5): x(b),y(b){cout << "A(int a)" << endl;cout << x << " " << y << endl;};A(const A&a){x = a.x;y = a.y;cout << "A(A&a)" << endl;}private:int x;int y;
};int main()
{int a = 6;A tmp = a;return 0;
}
输出的结果:

当构造函数与需要类型转换的内置类型变量无关时。上面的例子就是,虽然传入了a但是没有使用a对类中的成员变量初始化,而是使用b的缺省值进行初始化,这时虽然将int类型转换为A类型但是是与a无关的。
进阶:
上面在演示程序逻辑时,a变量作为实参,去匹配构造函数的参数列表时,并没有说参数的数量,实际上a不只是能匹配一个参数的构造函数,还可以匹配多个参数的构造函数(其他第一个参数,其他的参数都需要有缺省值才行)。其实自定义的类型的隐示类型转换就是通过直接构造函数完成的,那能不能传入多个不同的类型转化为自定义类型?
class A
{
public://构造函数A(int a,int b): x(a),y(b){cout << "A(int a)" << endl;cout << x << " " << y << endl;};
private:int x;int y;
};
int main()
{int a = 6;int b = 7;A tmp = {a,b};return 0;
}
程序运行的结果:

结论:
1.并不是只能一个类型进行隐示类型转换,多个类型也是可以隐示类型转换的,多个类型隐示类型转换的步骤和上面一样,只是这次向构造函数的传参不是一个。
2.构造函数不仅可以构造和初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
1.2.1 explicit关键字
上面讲了自定义类型的隐示类型转换是通过构造函数来完成隐示类型转换,当我们不允许隐示类型转换时,会在构造函数前面加上explicit这个关键字。
class A
{
public://构造函数explicit A(int a,int b): x(a),y(b){cout << "A(int a)" << endl;cout << x << " " << y << endl;};
private:int x;int y;
};
int main()
{int a = 6;int b = 7;A tmp = {a,b};return 0;
}
这段程序是报错的,原因就是在构造函数前面加上了explicit关键字,还进行了隐示类型转换。
2. Static关键字
2.1 Static类成员
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量。
特性:
- 静态成员为所有的类型共有,放在静态区。
- 静态成员变量只创建一次,静态成员变量必须在类的外面定义,定义是不加static关键字。
- 静态成员变量可以使用:类名:静态成员或者对象.静态成员访问。
- 静态成员变量也是类型的成员,是受到public,private和protect的保护的。
代码演示
class A
{
public://构造函数A(int a,int b): x(a),y(b){cout << "A(int a)" << endl;cout << x << " " << y << endl;};
private:int x;int y;static int c;
};
int A:: c = 5;
int main()
{int a = 6;int b = 7;A tmp = {a,b};return 0;
}
2.2 Static修饰成员函数
用static修饰的成员函数,称之为静态成员函数
特性:
- 静态成员函数被static修饰,没有this指针,只能访问静态成员变量。
- 静态成员函数是不在成员函数存储的地方的。
代码演示:
class A
{
public://构造函数A(int a, int b): x(a),y(b){};static int get(){return c;}
private:int x;int y;//静态成员变量的声明static int c;
};
//静态成员变量的定义
int A:: c = 5;
int main()
{int a = 6;int b = 7;A tmp = {a,b};cout << tmp.get() << endl;;return 0;
}
输出的结果:

3. const修饰
const放在成员函数的参数括号的后面,这个const是用来修饰*this指针的,是为了不让通过this指针修改类中的成员变量。如:const *this
代码演示:
class A
{
public://构造函数A(int a, int b): x(a),y(b){cout << "x=" << x <<" " << "y=" << y << endl;};//const修饰的成员函数void get()const{//这个是不能修改类中的成员变量的x = 4;y = 5;}
private:int x;int y;static int c;
};
代码结果:
这个代码是报错的

4. 友元类和友元函数
4.1 友元函数
友元函数可以直接访问类的私有成员变量,它的定义是在类的外面的普通函数,不属于任何类,但是需要在类中声明,声明时需要加friend关键字。
特性:
- 友元函数可以访问私有和保护成员变量
- 友元函数没有this指针,所有不能const修饰
- 友元函数可以在类的任何位置进行声明,不受访问限定符的限制
- 一个函数可以是多个类的友元函数
- 友元函数和普通函数的调用是一样的
代码演示:
#include<iostream>
using namespace std;
class A
{
public://构造函数A(int a, int b): x(a),y(b){cout << "x=" << x <<" " << "y=" << y << endl;};friend void get(int& n, int& m, const A& wa);
private:int x;int y;static int c;
};
int A:: c = 5;void get(int& n,int& m,const A& wa)
{n = wa.x;m = wa.y;}
int main()
{int a = 6;int b = 7;A tmp = {a,b};int n, m;get(n, m, tmp);cout << "n=" << n << " "<<"m=" << m << endl;return 0;
}
代码运行结果:

**结论:**当我们在类的外部定义的普通函数需要使用类中的成员变量时,就可以在该类中声明友元函数,这个该普通函数就可以访问类中的成员变量。
4.2 友元类
有一个类是另一个类的友元类,该类型中的成员函数都另一个类的友元函数,该类的成员函数都可以访问另一个类的非公有成员变量。
特性:
- 友元关系是单向的,比如:A是B的友元类,A是可以访问B中的成员变量,但是B不是A的友元,B是不可以访问A中的成员变量的。
- 友元关系是不能传递的,A是B的友元,B是C的友元,这并不意味这A是C的友元。
- 友元关系是不能继承的。
代码演示:
#include<iostream>
using namespace std;class A
{
public://构造函数A(int a, int b): x(a),y(b){cout << "x=" << x <<" " << "y=" << y << endl;};friend class B;
private:int x;int y;static int c;
};
class B
{
public:int get(const A& a){return a.x;}};
int A:: c = 5;
int main()
{int a = 6;int b = 7;A tmp = {a,b};B tm;int n = tm.get(tmp);cout << n << endl;return 0;
}
代码运行的结果:

5. 内部类
概念:一个类定义在另一个类的内部,就称该类是另一个类的内部类。
特性:
- 内部类和外部类是平等的,内部类虽然在外部类中定义,但是内部类是不属于外部类的,sizeof(外部类)是不会算上内部类的。
- 内部类是外部类的友元类,他们之间遵循友元关系的定义和用法,但是外部类不是内部类的友元。
- 内部类可以定义在外部类的任何位置。
- 内部类是可以直接访问外部类中的static成员变量的,不需要加上对象名/类名。
- 虽然说内部类和外部类是平等的,但是内部类需要定义是需要通过外部类的。
代码演示:
#include<iostream>
using namespace std;class A
{
public://构造函数A(int a, int b): x(a),y(b){cout << "x=" << x <<" " << "y=" << y << " " << "c=" << c << endl;};class B{public:int get(A& a){return c;}};
private:int x;int y;static int c;
};int A:: c = 5;int main()
{int a = 6;int b = 7;A tmp = {a,b};A::B p;cout << p.get(tmp) << endl;return 0;
}
代码的运行结果:

6. 匿名对象
特性
- 匿名对象是不需要取名字的
- 匿名对象的生命周期只有它定义的这一行
代码演示:
#include<iostream>
using namespace std;
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};
int main()
{A();return 0;
}
程序运行的结果:

7. 拷贝时编译器的一些优化
- 连续构造+拷贝构造直接优化为直接构造。
- 连续拷贝构造+拷贝构造直接优化为拷贝构造。
- 连续拷贝+赋值重载是没有办法进行优化的。
相关文章:
类和对象——相关的零碎知识
前提提示: 其实C中的类和对象,最重要的是6个默认函数,如有忘记,请移步到:类和对象。本章是对于一些细节知识的补充和拓展。 1. 隐示类型转换 在运算时,运算符左右两边的操作数的类型不同,编译器…...
【hadoop大数据集群 1】
hadoop大数据集群 1 文章目录 hadoop大数据集群 1一、环境配置1.安装虚拟机2.换源3.安装工具4.安装JDK5.安装Hadoop 一、环境配置 折腾了一下午/(ㄒoㄒ)/~~ 1.安装虚拟机 参考视频:https://www.bilibili.com/video/BV18y4y1G7JA?p17&vd_sourcee15e83ac6b22a…...
TQSDRPI开发板教程:实现PL端的UDP回环与GPSDO
本教程将完成一个全面的UDP运行流程与GPSDO测试,从下载项目的源代码开始,通过编译过程,最终将项目部署到目标板卡上运行演示。此外,我们还介绍如何修改板卡的IP地址,以便更好地适应您的网络环境或项目需求。 首先从Gi…...
array.some() ==> 查找数组list中,是否有包含与当前currKey的值不一样的misId
需求: const list [ {misId: e, name: 小白}, {misId: e, name: 小白白}, {misId: r, name: 小王}, {misId: r, name: 小小王} ] let currKey r 查找数组list中,是否有包含与当前currKey的值不一样的misId 解决: 要查找数组lis…...
最简单的typora+gitee+picgo配置图床
typoragiteepicgo图床 你是否因为管理图片而感到头大?是时候了解一下 Typora、Gitee 和 PicGo 这个超级三剑客了,它们可以帮你轻松打造自己的图床,让你的博客图片管理变得简单又有趣。让我们开始这场神奇的图床之旅吧! Typora …...
【黄啊码】GPT的相关名词解释
GPT是一种基于互联网的、可用数据来训练的、文本生成的深度学习模型 GPT的核心技术是变换器(Transformer),这是一种神经网络结构,可以有效地处理序列数据,比如文本、语音、图像等。GPT使用了大量的预训练数据&#…...
git stash 命令详解
git stash 描述 git stash 命令用于将当前工作目录中的未提交更改(包括暂存区和工作区的更改)保存到一个栈中,并恢复工作目录到干净的 HEAD 状态。这样您可以在不提交当前更改的情况下,切换到其他分支或进行其他操作。后续可以通…...
txt格式单词导入有道词典生词本 (java代码方式)
txt格式单词导入有道词典生词本 (java代码方式) 首先要求txt文档里单词的格式,大概需要像这种: 每行是一个单词,格式为:英文单词空格词性单词意思。 注意 导出单词本的名字就是你 txt 文件的名字 我这里是 公共英语三级 单词本 …...
轨迹优化 | 基于ESDF的共轭梯度优化算法(附ROS C++/Python仿真)
目录 0 专栏介绍1 数值优化:共轭梯度法2 基于共轭梯度法的轨迹优化2.1 障碍约束函数2.2 曲率约束函数2.3 平滑约束函数 3 算法仿真3.1 ROS C实现3.2 Python实现 0 专栏介绍 🔥课程设计、毕业设计、创新竞赛、学术研究必备!本专栏涉及更高阶的…...
深入浅出WebRTC—ALR
ALR(Application Limited Region)指的是网络传输过程中,由于应用层的限制(而非网络拥塞)导致带宽未被充分利用的情况。在这种情况下,应用层可能因为处理能力、手动配置或其他因素无法充分利用可用带宽&…...
BSV区块链技术现实应用原理解析
BSV区块链以其卓越的可扩展性、坚如磐石的安全性、极低的交易成本等特性,成为满足企业当下需求并为企业未来成功奠基铺路的理想技术。 BSV协会近期发布了一个题为《驾驭数字化转型:在自动化世界中建立信任——区块链在数据保护和交易优化中的角色》的报…...
七大基于比较的排序算法
目录 一、基于比较的排序算法概述 1. 插入排序(Insertion Sort) 2. 选择排序(Selection Sort) 3. 冒泡排序(Bubble Sort) 4. 归并排序(Merge Sort) 5. 快速排序(Qu…...
web前端 React 框架面试200题(四)
面试题 97. React 两种路由模式的区别?hash和history? 参考回答: 1: hash路由 hash模式是通过改变锚点(#)来更新页面URL,并不会触发页面重新加载,我们可以通过window.onhashchange监听到hash的改变,从而处…...
5.Fabric的共识机制
在Fabric中,有以下3中典型共识机制。 Solo共识 solo共识机制只能用于单节点模式,即只能有一个Orderer节点,因此,其共识过程很简单,每接收到一个交易信息,就在共识模块的控制下产生区块并广播给节点存储到账本中。 Solo 模式下的共识只适用于一个Orderer节点,所以可以在…...
【safari】react在safari浏览器中,遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。如何解决
在safari浏览器中,可能会遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。 PS:由于useState是一个普通的函数, 定义为() > void;因此此处不能用await/async替代setTimeout,只能用在返…...
京准:GPS北斗卫星授时信号安全隔离防护装置
京准:GPS北斗卫星授时信号安全隔离防护装置 京准:GPS北斗卫星授时信号安全隔离防护装置 1、主要特点 ★信号加固功能: GPS/BDS单系统信号拒止情况下(包含受到GPS L1欺骗干扰、GPS L1压制干扰、BDS B1欺骗干扰、BDS B1压制干扰&…...
解决方案架构师系列 - AWS - Pinpoint
AWS Pinpoint介绍 Amazon Pinpoint 为营销人员和开发人员提供了一款可自定义的工具,助力他们大规模地开展跨渠道、行业和活动的客户通信。 Amazon Pinpoint是一个全面的客户参与平台,旨在帮助营销人员和开发人员大规模地开展跨渠道、行业和活动的客…...
MF173:将多个工作表转换成PDF文件
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…...
Docker、containerd、CRI-O 和 runc 之间的区别
容器与 Docker 这个名称并不紧密相关。你可以使用其他工具来运行容器 您可以使用 Docker 或一堆非Docker 的其他工具来运行容器。docker只是众多选项之一,Docker(公司)在生态系统中创建了一些很棒的工具,但不是全部。 容器方面有…...
PRISM-Python 中的规则一个简单的 Python 规则感应系统
欢迎来到雲闪世界.PRISM 是一种现有算法(尽管我确实创建了一个 Python 实现),PRISM 相对简单,但在机器学习中,有时最复杂的解决方案效果最好,有时最简单的解决方案效果最好。然而,当我们希望建立…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
