详解C++类与对象(四)
文章目录
- 1.类型转换
- 1.1 前言
- 1.2 类型转换的性质
- 2.static成员
- 2.1 前言
- 2.2 static的基本概念
- 3.友元
- 4.内部类
- 5.匿名对象
1.类型转换
1.1 前言
在C++中,由于程序员可以自己显示定义一个新的类。这样就会出现一个问题:程序员自己显示定义的类类型与编译器中自带的隐式定义的类型发生了冲突,无法进行匹配。就像整型无法赋值浮点型的数.
int a = 1.0;
//无法赋值浮点型
因此。C++支持 内置类型 / 隐式类型 转换为类类型对象。
1.2 类型转换的性质
- C++想要实现类型转换,需要有相关内置类型为参数的构造函数。
- 构造函数前面加 explicit ,该构造函数就不再支持隐式类型转换。
- 显示定义的类型也可以转换为隐式定义的类型,也需要相应的构造函数支持。
#include<iostream>
using namespace std;class A
{
public:// 构造函数explicit就不再⽀持隐式类型转换// explicit A(int a1)A(int a1)//显示定义的类型转换为int类型:_a1(a1){}//explicit A(int a1, int a2)A(int a1, int a2):_a1(a1), _a2(a2){}void Print(){cout << _a1 << " " << _a2 << endl;}int Get() const{return _a1 + _a2;}private:int _a1 = 1;int _a2 = 2;
};class B
{
public:B(const A& a):_b(a.Get()){}private:int _b = 0;
};int main()
{//转换的逻辑过程:// 步骤一:1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3// 步骤二:编译器遇到连续构造+拷⻉构造->优化为直接构造,这里类型转换完成A aa1 = 1;//1的隐式类型是int,A的类型是A。这里1被转换为A类型aa1.Print();const A& aa2 = 1;A aa3 = { 2,2 };//多参数的类型转换,C++11之后才开始支持。// aa3隐式类型转换为b对象// 原理跟上⾯类似B b = aa3;//A类型的aa3转换为B类型//显式定义转换为隐式定义也是这个逻辑const B& rb = aa3;//引用,没有拷贝过程,提高程序效率return 0;
}
2.static成员
2.1 前言
static 。中文意思是静态的,在C++中作为静态成员的关键字。用来修饰静态成员。那么,在C++中,static 具体的作用有哪些呢?接下来为各位介绍。
2.2 static的基本概念
- 在C++中,用 static 修饰的成员变量称为静态成员变量。
- 由于静态成员变量可以被所有的类对象使用,不属于某一个类对象,存放在静态区中。所以静态成员变脸只能在类外初始化。
- 用 static 修饰的成员函数,称为静态成员函数。静态成员函数没有 this 指针。
- 非静态成员函数可以访问静态成员和静态成员函数;静态成员函数不能访问非静态成员,因为没有 this 指针。
- 突破类域就可以访问静态成员和静态成员函数。通过 ::静态成员 或者 对象.(静态成员) 等两种方式来访问静态成员和静态成员函数。
- 静态成员受public,private,protected 等访问限制符的限制。
class A
{
public:A(){++_scount;}A(const A& t){++_scount;}~A(){--_scount;}static int GetACount()//静态成员函数没有this指针{//_a = 1;//静态成员函数不能访问非静态成员return _scount;}
private://进入private,静态成员则无法被其他类访问// 类⾥⾯声明static int _scount;//静态成员变量int _a;
};class B
{
public:private://int _b1 = A::_scount;//静态成员可以被所有的类访问,但是同时也受到访问限制符的限制
};// 类外⾯初始化
int A::_scount = 0;int main()
{cout << A::GetACount() << endl;//A::GetACount是访问静态成员函数的一种方式A a1, a2;A a3(a1);cout << A::GetACount() << endl;cout << a1.GetACount() << endl;//cout << A::_scount << endl;// 编译报错:error C2248: “A::_scount”: ⽆法访问 private 成员(在“A”类中声明)return 0;
}
3.友元
友元包括友元函数和友元类,本质上是一种突破类访问限定符封装的方式。让本来封装起来的函数或者类能被另一个类使用。
- 在函数声明或者类声明的前面加friend,并且把友元声明放到⼀个类的里面。
- 外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,它不是类的成员函数。
- 友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
- ⼀个函数可以是多个类的友元函数。
- 友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员。
- 友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。
- 友元类关系不能传递,如果A是B的友元, B是C的友元,但是A不是C的友元。
- 友元有时提供了便利。但是友元会增加耦合度,破坏封装,与大型项目中低耦合高聚度的要求相违,所以友元不宜多用。
// 前置声明,否则A的友元函数声明编译器不认识B
class B;class A
{// 友元声明friend class B;// 友元声明 函数类型和名称的前面加上friendfriend void func(const A& aa, const B& bb);//一个函数可以是多个类的友元//外部友元函数func可以访问类里面的私有成员_a1和_a2private:int _a1 = 1;int _a2 = 2;
};class B
{friend class C;//友元关系不共享,A是B的友元,B是C的友元,但是A不是C的友元
public:// 友元声明friend void func(const A& aa, const B& bb);void func1(const A& aa)//友元类的单向关系。A是B的友元,但是B不是A的友元{cout << aa._a1 << endl;cout << _b1 << endl;}//friend class C;//友元声明可以在类的任何地方。一般情况下都是放在类的第一行void func2(const A& aa){cout << aa._a2 << endl;cout << _b2 << endl;}
private://friend class C;//友元声明可以在类的任何地方。一般情况下都是放在类的第一行int _b1 = 3;int _b2 = 4;//friend class C;//友元声明可以在类的任何地方。一般情况下都是放在类的第一行
};class C
{
public:private:int _c1 = 5;
};void func(const A& aa, const B& bb)
{cout << aa._a1 << endl;cout << bb._b1 << endl;
}int main()
{A aa;B bb;bb.func1(aa);bb.func1(aa);return 0;
}
4.内部类
-
如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,它只是受外部类类域限制和访问限定符限制,所以外部类实例化的对象中不包含内部类的实例化。
-
内部类默认是外部类的友元类。
-
内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到 private / protected 位置,那么A类就是B类的专属内部类,其他地方都用不了。
class A
{
private:static int _k;int _h = 1;public:class B // B是A的内部类。B默认就是A的友元{public:void foo(const A& a){cout << _k << endl; //可以这样调用A的私有成员cout << a._h << endl; //也可以这样调用A的私有成员}};
};int A::_k = 1;//static定义的成员是静态变量,可以在全局赋值int main()
{cout << sizeof(A) << endl;//由于static定义的成员不参与组成类的大小,所以A的大小为4个字节,一个整型A::B b;//由于内部类受到类域的限制,所以使用的时候需要声明A aa;//外部类则没有限制b.foo(aa);return 0;
}
5.匿名对象
- 用类型(实参) 定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参) 定义出来的叫有名对象。
- 匿名对象生命周期只在当前一行,⼀般临时定义⼀个对象当前用⼀下即可,就可以定义匿名对象。
- const定义的匿名对象则可以延长使用寿命。
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};class Solution {
public:int Sum_Solution(int n) {//...return n;}
};int main()
{A aa1;aa1 = 1;//有名对象// A aa1(); //不能这么定义对象,因为编译器⽆法识别下⾯是⼀个函数声明,还是对象定义// A aa2(2);// 我们可以这么定义匿名对象,匿名对象的特点不⽤取名字,// 但是他的⽣命周期只有这⼀⾏,我们可以看到下⼀⾏它就会⾃动调⽤析构函数A();A(1);//匿名对象const A& r = A();//const定义的对象声明周期与r相同,r销毁匿名对象析构// 匿名对象在这样场景下就很好⽤,当然还有⼀些其他使⽤场景,这个我们以后遇到了再说Solution().Sum_Solution(10);return 0;
}
运行结果解释:
相关文章:

详解C++类与对象(四)
文章目录 1.类型转换1.1 前言1.2 类型转换的性质 2.static成员2.1 前言2.2 static的基本概念 3.友元4.内部类5.匿名对象 1.类型转换 1.1 前言 在C中,由于程序员可以自己显示定义一个新的类。这样就会出现一个问题:程序员自己显示定义的类类型与编译器中…...
Pandas处理和分析嵌套JSON数据:从字符串到结构化DataFrame
在数据分析领域,我们经常遇到需要从非结构化数据中提取有用信息的场景。特别是当数据以JSON字符串的形式出现时,如何有效地将其转换为结构化的表格形式,以便进行进一步的分析和处理,成为了一个常见的挑战。本文将通过一个具体的例…...

【强化学习入门笔记】1.5 贝尔曼最优公式
本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 课程视频网址:https://space.bilibili.com/2044042934 1.5.1 定义 1.5.1.1 Contraction mapping theorem (收缩映射定理) fixed point(不动点) 如果 x ∗ x^* x∗满足下式, x ∗ x^* x∗称之为…...
编码问题技术探讨:IDE全局GBK与项目UTF-8引发的中文乱码
在软件开发过程中,编码问题一直是开发者们需要面对和解决的难题之一。尤其是在使用IDE(集成开发环境)时,如果全局编码设置与项目编码设置不一致,往往会导致中文乱码的问题。本文将深入探讨这一问题的背景、示例以及解决…...

SpringBoot两天
SpringBoot讲义 什么是SpringBoot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式…...

自动化立体仓库项目任务调度系统中任务流程可视化实现
在运维自动化平台中,任务系统无疑是最核心的组成部分之一。它承担着所有打包编译、项目上线、日常维护等运维任务的执行。通过任务系统,我们能够灵活地构建满足不同需求的自定义任务流。早期的任务流后端采用了类似列表的存储结构,根据任务流内子任务的排序依次执行,尽管通…...

计算机毕业设计hadoop+spark民宿推荐系统 民宿数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习 大数据毕业设计
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Java中OGNL表达式语言的使用
文章目录 OGNL 介绍OGNL 使用场景- ognl- 主要功能- 注意事项- Ognl类的主要方法- 设置值- 获取值- 使用示例 - MybatisJava原生表达式的使用 - Fastjson- JSONPath类的主要方法- 主要功能- JSONPath的优势- 使用示例 Spring不选择OGNL的原因 OGNL 介绍 OGNL(Objec…...

[HCTF 2018]WarmUp-滑稽
启动场景打开链接,出现一下图片 F12查看代码出现一个注释,应该在这个文件中, 进入到该页面,出现一段代码 <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["sourc…...

JAVAWeb——maven、SpringBoot、HTTP、Tomcat
目录 1.maven a.概述 b.作用 c.仓库 b.坐标 c.依赖管理 2.SpringBoot 3.HTTP a.概述 b.请求协议 c.响应协议 d.协议解析 4.Tomcat a.Web服务器 b.Tomcat c.SpringBoot与Tomcat关系 1.maven a.概述 Maven是apache旗下的一个开源项目,是一款用于管理…...

【C++】—— set 与 multiset
【C】—— map 与 set 1 序列式容器和关联式容器2 set 系列的使用2.1 set 和 multiset 参考文档2.2 set 类的介绍2.3 set 的迭代器和构造2.4 set的增删查2.4.1 insert2.4.2 find 与 erase2.4.3 count 2.5 lower_bound 与 upper_bound2.6 multiset 与 set 的差异2.6.1 不再去重2…...
蓝桥杯-扫雷
这题不难,就是麻烦一点,这里暴力求解了直接 题目链接: 扫雷 AC代码: import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan ne…...

黑马JavaWeb-day06、07、08(SQL部分) _
文章目录 MYSQL概述数据模型SQL简介SQL分类 DDL数据库操作表操作 DML增(INSERT)改(UPDATE)删(DELETE) DQL基本查询条件查询(where)分组查询(group by)排序查询…...
三十五:Wireshark的捕获过滤器
Wireshark 是一个广泛使用的网络协议分析工具,主要用于捕获和分析网络流量。它支持丰富的协议分析,并提供了多种过滤方式,以便用户在大量数据中精确地找到自己关注的内容。在Wireshark中,过滤器可以分为两类:捕获过滤器…...
第9章 大模型的有害性(上)
9.1 引言 本章将探讨大型语言模型(LLMs)可能带来的有害性,重点讨论以下几个方面: 性能差异社会偏见和刻板印象 在后续内容中,还会涉及其他层面的危害,如有害信息、虚假信息、隐私和安全风险、版权问题、…...

遗传算法与深度学习实战(26)——编码卷积神经网络架构
遗传算法与深度学习实战(26)——编码卷积神经网络架构 0. 前言1. EvoCNN 原理1.1 工作原理1.2 基因编码 2. 编码卷积神经网络架构小结系列链接 0. 前言 我们已经学习了如何构建卷积神经网络 (Convolutional Neural Network, CNN),在本节中&a…...
Linux无线网络配置工具:iwconfig vs iw
在Linux系统中,无线网络配置和管理是网络管理员和开发者的常见任务。本文将详细介绍两个常用的无线网络配置命令行工具:iwconfig 和 iw,并对比它们之间的区别,帮助您更好地选择合适的工具进行无线网络配置。 一、iwconfig 简介 …...

RabbitMQ介绍及安装
文章目录 一. MQ二. RabbitMQ三. RabbitMQ作用四. MQ产品对比五. 安装RabbitMQ1. 安装erlang2. 安装rabbitMQ3. 安装RabbitMQ管理界⾯4. 启动服务5. 访问界面6. 添加管理员用户7. 重新登录 一. MQ MQ( Message queue ), 从字⾯意思上看, 本质是个队列, FIFO 先⼊先出ÿ…...

借助 AI 工具,共享旅游-卡-项目助力年底增收攻略
年底了,大量的商家都在开始筹备搞活动,接下来的双十二、元旦、春节、开门红、寒假,各种活动,目的就是为了拉动新客户。 距离过年还有56 天,如何破局? 1、销售渠道 针对旅游卡项目,主要销售渠道…...

Docker Compose 和 Kubernetes 之间的区别?
一、简介🎀 1.1 Docker Compose Docker Compose 是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排,可以管理多个 Docker 容器组成一个应用。你只需定义一个 YAML 格式的配置文件 docker-compose.yml ,即可创建并…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...

若依项目部署--传统架构--未完待续
若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加,传统开发模式存在效率低,重复劳动多等问题。若依项目通过整合主流技术框架&…...