当前位置: 首页 > news >正文

详解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 类型转换的性质

  1. C++想要实现类型转换,需要有相关内置类型为参数的构造函数。
  2. 构造函数前面加 explicit ,该构造函数就不再支持隐式类型转换。
  3. 显示定义的类型也可以转换为隐式定义的类型,也需要相应的构造函数支持。
#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的基本概念

  1. 在C++中,用 static 修饰的成员变量称为静态成员变量。
  2. 由于静态成员变量可以被所有的类对象使用,不属于某一个类对象,存放在静态区中。所以静态成员变脸只能在类外初始化。
  3. 用 static 修饰的成员函数,称为静态成员函数。静态成员函数没有 this 指针。
  4. 非静态成员函数可以访问静态成员和静态成员函数;静态成员函数不能访问非静态成员,因为没有 this 指针。
  5. 突破类域就可以访问静态成员和静态成员函数。通过 ::静态成员 或者 对象.(静态成员) 等两种方式来访问静态成员和静态成员函数。
  6. 静态成员受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.友元

友元包括友元函数和友元类,本质上是一种突破类访问限定符封装的方式。让本来封装起来的函数或者类能被另一个类使用。

  1. 在函数声明或者类声明的前面加friend,并且把友元声明放到⼀个类的里面。
  2. 外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,它不是类的成员函数。
  3. 友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
  4. ⼀个函数可以是多个类的友元函数。
  5. 友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员。
  6. 友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。
  7. 友元类关系不能传递,如果A是B的友元, B是C的友元,但是A不是C的友元。
  8. 友元有时提供了便利。但是友元会增加耦合度,破坏封装,与大型项目中低耦合高聚度的要求相违,所以友元不宜多用。
// 前置声明,否则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.内部类

  1. 如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,它只是受外部类类域限制和访问限定符限制,所以外部类实例化的对象中不包含内部类的实例化。

  2. 内部类默认是外部类的友元类。

  3. 内部类本质也是⼀种封装,当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.匿名对象

  1. 用类型(实参) 定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参) 定义出来的叫有名对象。
  2. 匿名对象生命周期只在当前一行,⼀般临时定义⼀个对象当前用⼀下即可,就可以定义匿名对象。
  3. 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中&#xff0c;由于程序员可以自己显示定义一个新的类。这样就会出现一个问题&#xff1a;程序员自己显示定义的类类型与编译器中…...

Pandas处理和分析嵌套JSON数据:从字符串到结构化DataFrame

在数据分析领域&#xff0c;我们经常遇到需要从非结构化数据中提取有用信息的场景。特别是当数据以JSON字符串的形式出现时&#xff0c;如何有效地将其转换为结构化的表格形式&#xff0c;以便进行进一步的分析和处理&#xff0c;成为了一个常见的挑战。本文将通过一个具体的例…...

【强化学习入门笔记】1.5 贝尔曼最优公式

本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 课程视频网址&#xff1a;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引发的中文乱码

在软件开发过程中&#xff0c;编码问题一直是开发者们需要面对和解决的难题之一。尤其是在使用IDE&#xff08;集成开发环境&#xff09;时&#xff0c;如果全局编码设置与项目编码设置不一致&#xff0c;往往会导致中文乱码的问题。本文将深入探讨这一问题的背景、示例以及解决…...

SpringBoot两天

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

自动化立体仓库项目任务调度系统中任务流程可视化实现

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

计算机毕业设计hadoop+spark民宿推荐系统 民宿数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Java中OGNL表达式语言的使用

文章目录 OGNL 介绍OGNL 使用场景- ognl- 主要功能- 注意事项- Ognl类的主要方法- 设置值- 获取值- 使用示例 - MybatisJava原生表达式的使用 - Fastjson- JSONPath类的主要方法- 主要功能- JSONPath的优势- 使用示例 Spring不选择OGNL的原因 OGNL 介绍 OGNL&#xff08;Objec…...

[HCTF 2018]WarmUp-滑稽

启动场景打开链接&#xff0c;出现一下图片 F12查看代码出现一个注释&#xff0c;应该在这个文件中&#xff0c; 进入到该页面&#xff0c;出现一段代码 <?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旗下的一个开源项目&#xff0c;是一款用于管理…...

【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…...

蓝桥杯-扫雷

这题不难&#xff0c;就是麻烦一点&#xff0c;这里暴力求解了直接 题目链接&#xff1a; 扫雷 AC代码&#xff1a; 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增&#xff08;INSERT&#xff09;改&#xff08;UPDATE&#xff09;删&#xff08;DELETE&#xff09; DQL基本查询条件查询&#xff08;where&#xff09;分组查询&#xff08;group by&#xff09;排序查询…...

三十五:Wireshark的捕获过滤器

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;主要用于捕获和分析网络流量。它支持丰富的协议分析&#xff0c;并提供了多种过滤方式&#xff0c;以便用户在大量数据中精确地找到自己关注的内容。在Wireshark中&#xff0c;过滤器可以分为两类&#xff1a;捕获过滤器…...

第9章 大模型的有害性(上)

9.1 引言 本章将探讨大型语言模型&#xff08;LLMs&#xff09;可能带来的有害性&#xff0c;重点讨论以下几个方面&#xff1a; 性能差异社会偏见和刻板印象 在后续内容中&#xff0c;还会涉及其他层面的危害&#xff0c;如有害信息、虚假信息、隐私和安全风险、版权问题、…...

遗传算法与深度学习实战(26)——编码卷积神经网络架构

遗传算法与深度学习实战&#xff08;26&#xff09;——编码卷积神经网络架构 0. 前言1. EvoCNN 原理1.1 工作原理1.2 基因编码 2. 编码卷积神经网络架构小结系列链接 0. 前言 我们已经学习了如何构建卷积神经网络 (Convolutional Neural Network, CNN)&#xff0c;在本节中&a…...

Linux无线网络配置工具:iwconfig vs iw

在Linux系统中&#xff0c;无线网络配置和管理是网络管理员和开发者的常见任务。本文将详细介绍两个常用的无线网络配置命令行工具&#xff1a;iwconfig 和 iw&#xff0c;并对比它们之间的区别&#xff0c;帮助您更好地选择合适的工具进行无线网络配置。 一、iwconfig 简介 …...

RabbitMQ介绍及安装

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

借助 AI 工具,共享旅游-卡-项目助力年底增收攻略

年底了&#xff0c;大量的商家都在开始筹备搞活动&#xff0c;接下来的双十二、元旦、春节、开门红、寒假&#xff0c;各种活动&#xff0c;目的就是为了拉动新客户。 距离过年还有56 天&#xff0c;如何破局&#xff1f; 1、销售渠道 针对旅游卡项目&#xff0c;主要销售渠道…...

Docker Compose 和 Kubernetes 之间的区别?

一、简介&#x1f380; 1.1 Docker Compose Docker Compose 是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的快速编排&#xff0c;可以管理多个 Docker 容器组成一个应用。你只需定义一个 YAML 格式的配置文件 docker-compose.yml &#xff0c;即可创建并…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...