[杂学笔记] 封装、继承、多态,堆和栈的区别,堆和栈的区别 ,托管与非托管 ,c++的垃圾回收机制 , 实现一个单例模式 注意事项

文章目录

      • 1.封装、继承、多态
      • 2. 堆和栈的区别
      • 3.指针和引用的区别
      • 4. 托管与非托管
      • 5. c++的垃圾回收机制
      • 6. 实现一个单例模式 注意事项

1.封装、继承、多态

  • 封装就是将数据和内部的方法封装到一个类中,对外隐藏内部实现细节,但是留下了公共接口提供给外部使用 。
  • 继承:子类继承父类的属性和方法,并对其进行延申,使用代码复用和功能扩展。
  • 多态:不同的对象在使用同一个函数或者在同一个环境下有不同的行为。

关于多态

多态就是不同的类对象去调用同一个函数产生了不同的行为 1.必须通过基类的引用或者指针调用虚函数 2.被调用的函数必须是虚函数,且派生类必须对虚函数进行重写。

  • 静态多态:体现在函数重载和运算符重载方面,编译阶段就已经确定要调用的函数了,静态多态的执行效率高
  • 动态多态:父类声明虚函数,子类重写虚函数,通过父类的指针或者引用去调用虚函数,程序会在运行的时候根据指针或者引用所指向的实际对象的类型来决定调用哪一个版本的虚函数。

但在底层实际上是,创建子类的时候,子类重写的虚函数会覆盖虚函数表中的地址,父类指针指向子类对象的时候,访问虚函数表地址访问的就是子类覆盖后的地址。

2. 堆和栈的区别

栈区作用:

存储函数内部定义的局部变量和函数传递的参数,当函数被调用的时候,这些局部变量都会被分配内存,函数调用结束之后,又会将这些占用的内存自动释放掉。还会保存函数的一些调用信息,例如函数调用的返回指针,栈帧指针等等。这些信息用于函数调用结束后能正确的返回到调用的位置。

堆区作用:

主要用于动态的内存分配,提供给程序员在程序运行的时候根据需要动态的申请和释放内存的区域。C中提供malloc、calloc、realloc、free等进行操作,在C++当中使用new和delete运算符进行操作。

区别:

  • 栈区的内存分配和释放是系统自动完成的,而堆区的内存分配和释放操作需要我们手动完成
  • 栈区的内存分配效率会相对较高一些,栈区的内存分配和释放操作时通过移动指针完成的,所以会非常快,而堆区的话需要查找合适的空闲内存块、更新管理的内存分配表等等操作,所以销毁会低很多。

3.指针和引用的区别

  • 指针可以不初始化(会指向一个随机的地址),引用必须初始化
  • 指针需要通过解引用 * 操作符来获取指向的值,引用不需要解引用
  • 指针本身占用内存(通常为4字节或8字节,取决于平台),引用本身不占有额外空间,只是一个别名,指向已有的对象
  • 指针的const属性:const int* ptr = &a; // 指针所指向的值不能被修改,int* const ptr2 = &a; // 指针本身的地址不能被修改

关于使用场景 :

  • 指针就是一个地址,内部存放了区域的起始地址,可以用于接受动态分配的内存,创建数据结构时会用到大量的指针;
  • 引用的底层原理也是一个指针,只不过从上层来看是一个变量的别名。 两者在传参和函数返回值的场景下,可以减少数据的拷贝工作

4. 托管与非托管

托管和非托管是计算机编程领域中的两个术语,它们主要用来描述内存管理的方式。
  1. 托管代码(Managed Code):在托管环境中运行的代码,如.NET框架、Java虚拟机等。在这种环境下,内存管理和资源回收由运行环境(如CLR或JVM)自动处理。程序员不需要手动分配和释放内存,减少了因忘记释放内存而导致的内存泄漏等问题。同时,托管环境还会提供垃圾回收机制,自动回收不再使用的内存空间。

  2. 在托管环境中运行的代码,如.NET框架、Java虚拟机等。在这种环境下,内存管理和资源回收由运行环境(如CLR或JVM)自动处理。程序员不需要手动分配和释放内存,减少了因忘记释放内存而导致的内存泄漏等问题。同时,托管环境还会提供垃圾回收机制,自动回收不再使用的内存空间。

简而言之,托管代码的优势在于简化了内存管理,降低了开发难度和出错概率;而非托管代码则提供了更底层、更灵活的操作,但同时也要求开发者有更强的对系统资源管理的能力。

5. c++的垃圾回收机制

  1. c++基于引用计数的智能指针,已经很大程度上解决了内存泄漏的问题。
  2. 常用的stl容器已经集成了allocator(std::allocator是一个简单的分配器,它基于全局的new和delete操作符来分配和释放内存),在运行时建有默认的内存分配策略

6. 实现一个单例模式 注意事项

什么是单例模式?

  • 单例模式是一种设计模式(Design Pattern),设计模式就是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式的目的就是为了可重用代码、让代码更容易被他人理解、保证代码可靠性程序的重用性。

  • 单例模式指的就是一个类只能创建一个对象,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

  • 比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象同一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

单例模式有两种实现方式,分别是饿汉模式和懒汉模式:

饿汉模式 :

单例模式的饿汉实现方式如下:

  1. 将构造函数设置为私有,并将拷贝构造函数和赋值运算符重载函数设置为私有或删除,防止外部创建或拷贝对象。
  2. 提供一个指向单例对象的static指针,并在程序入口之前完成单例对象的初始化。
  3. 提供一个全局访问点获取单例对象。
class Singleton
{
public://3、提供一个全局访问点获取单例对象static Singleton* GetInstance(){return _inst;}
private://1、将构造函数设置为私有,并防拷贝Singleton(){}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;//2、提供一个指向单例对象的static指针static Singleton* _inst;
};//在程序入口之前完成单例对象的初始化
Singleton* Singleton::_inst = new Singleton;

线程安全相关问题:

  • 饿汉模式在程序运行主函数之前就完成了单例对象的创建,由于main函数之前是不存在多线程的,因此饿汉模式下单例对象的创建过程是线程安全的。
  • 后续所有多线程要访问这个单例对象,都需要通过调用GetInstance函数来获取,这个获取过程是不需要加锁的,因为这是一个读操作。
  • 当然,如果线程通过GetInstance获取到单例对象后,要用这个单例对象进行一些线程不安全的操作,那么这时就需要加锁了。

懒汉模式

单例模式的懒汉实现方式如下:

  1. 将构造函数设置为私有,并将拷贝构造函数和赋值运算符重载函数设置为私有或删除,防止外部创建或拷贝对象。
  2. 提供一个指向单例对象的static指针,并在程序入口之前先将其初始化为空。
  3. 提供一个全局访问点获取单例对象。
class Singleton
{
public://3、提供一个全局访问点获取单例对象static Singleton* GetInstance(){//双检查if (_inst == nullptr){_mtx.lock();if (_inst == nullptr){_inst = new Singleton;}_mtx.unlock();}return _inst;}
private://1、将构造函数设置为私有,并防拷贝Singleton(){}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;//2、提供一个指向单例对象的static指针static Singleton* _inst;static mutex _mtx; //互斥锁
};//在程序入口之前先将static指针初始化为空
Singleton* Singleton::_inst = nullptr;
mutex Singleton::_mtx; //初始化互斥锁

为什么需要双重检查

  1. 减少锁的使用:通过第一次检查,如果实例已经存在,直接返回实例,避免加锁,从而减少锁的使用频率,提高性能。
  2. 线程安全:通过第二次检查,确保在加锁后再次检查实例是否已经创建,避免多个线程同时创建多个实例,确保线程安全。
  3. 优点 : 减少锁的使用频率,提高性能。 缺点 : 需要两次检查,实现稍显复杂。

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

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

相关文章

【三维生成】StarGen:基于视频扩散模型的可扩展的时空自回归场景生成

标题:《StarGen: A Spatiotemporal Autoregression Framework with Video Diffusion Model for Scalable and Controllable Scene Generation》 项目:https://zju3dv.github.io/StarGen 来源:商汤科技、浙大CAD、Tetras.AI 文章目录 摘要一、…

【一个月备战蓝桥算法】递归与递推

字典序 在刷题和计算机科学领域,字典序(Lexicographical order)也称为词典序、字典顺序、字母序,是一种对序列元素进行排序的方式,它模仿了字典中单词的排序规则。下面从不同的数据类型来详细解释字典序: …

【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(成功版)

【Linux】【网络】UDP打洞–>不同子网下的客户端和服务器通信(成功版) 根据上个文章的分析 问题可能出现在代码逻辑上面 我这里重新查找资料怀疑: 1 NAT映射可能需要多次数据包的发送才能建立。 2 NAT映射保存时间太短&#xff…

SpaCy处理NLP的详细工作原理及工作原理框图

spaCy处理NLP的详细工作原理及工作原理框图 spaCy处理NLP的详细工作原理 spaCy是一个基于Python的开源自然语言处理(NLP)库,它提供了一系列高效且易用的工具,用于执行各种NLP任务,如文本预处理、文本解析、命名实体识…

C++ Primer 动态数组

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…

【Qt】ffmpeg照片提取、视频播放▲

目录 一、图像的成像原理: RGB成像原理: YUV成像原理: 二、多线程 三、ffmpeg解码(照片提取) 1.准备工作 (1)在工程文件夹里面新建三个文件夹 (2)在main函数中加…

⭐算法OJ⭐跳跃游戏【BFS+滑动窗口】(C++实现)Jump Game 系列 III,VII

⭐算法OJ⭐跳跃游戏【贪心算法】(C实现)Jump Game 系列 I,II 这篇文章介绍 跳跃游戏 的第三题和第七题,两道题目有异曲同工之妙,都运用了BFS广度优先搜索算法实现,难度相比于前两题较高,而且不同于更常见的…

【QGIS二次开发】地图显示与交互-01

1. 系统界面设计 设计的系统界面如下,很好还原了QGIS、ArcGIS等软件的系统界面,充分利用了QT中顶部工具栏、菜单栏、底部状态栏,实现了图层管理器、鹰眼图、工具箱三个工具面板。 菜单栏、工具栏、工具箱集成了系统中实现的全部功能&#x…

Skynet入门(一)

概念 skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。 设计初衷 如何充分利用它们并行运作数千个相互独立的业务。 模块设计建议 在 skynet 中,用服务 (service) 这…

threejs:用着色器给模型添加光带扫描效果

第一步:给模型添加光带 首先创建一个立方体,不进行任何缩放平移操作,也不要set position。 基础代码如下: 在顶点着色器代码里varying vec3 vPosition;vPosition position;获得threejs自动计算的顶点坐标插值(也就…

【时序预测】在线学习:算法选择(从线性模型到深度学习解析)

——如何为动态时序预测匹配最佳增量学习策略? 引言:在线学习的核心价值与挑战 在动态时序预测场景中(如实时交通预测、能源消耗监控),数据以流式(Streaming)形式持续生成,且潜在的…

Spring Boot如何利用Twilio Verify 发送验证码短信?

Twilio提供了一个名为 Twilio Verify 的服务,专门用于处理验证码的发送和验证。这是一个更为简化和安全的解决方案,适合需要用户身份验证的应用。 使用Twilio Verify服务的步骤 以下是如何在Spring Boot中集成Twilio Verify服务的步骤: 1.…

【Linux操作系统】VM17虚拟机安装Ubuntu22.04,图文详细记录

1.双击桌面的 VMware Workstation17 Player,点击“创建新虚拟机”,如下图所示。 2.选择“稍后安装操作系统”,点击“下一步”。如下图所示。 3.客户机操作系统选择“Linux”,版本选择“ Ubuntu 64位”,然后点击“下一…

软件工程---净室软件工程

净室软件工程是一种软件开发方法,旨在通过形式化的数据和严格的测试来提高软件的可靠性和减少缺陷的数量。它的核心思想是在软件开发过程中最小化或消除软件缺陷,从而提高软件的质量和可靠性。这种方法强调在软件生命周期的早期阶段使用形式化方法进行规…

迷你世界脚本区域接口:Area

区域接口:Area 彼得兔 更新时间: 2023-12-18 11:35:14 具体函数名及描述如下: 序号 函数名 函数描述 1 createAreaRect(...) 创建矩形区域 2 createAreaRectByRange(...) 创建矩形区域(通过范围) 3 destroyArea(...) 销毁区域 4 getAre…

C# 牵手DeepSeek:打造本地AI超能力

一、引言 在人工智能飞速发展的当下,大语言模型如 DeepSeek 正掀起新一轮的技术变革浪潮,为自然语言处理领域带来了诸多创新应用。随着数据隐私和安全意识的提升,以及对模型部署灵活性的追求,本地部署 DeepSeek 成为众多开发者和…

Linux--基础命令3

大家好,今天我们继续学习Linux的基础命令 mv命令 mv命令是move的缩写,可以用来移动文件或者将文件改名 move(rename) files,经常⽤来备份⽂件或者目录 语法: mv [ 选项 ] 源⽂件或目录 目标⽂件或目录 mv src[文件、目录] dst[路径、文…

【每日八股】计算机网络篇(三):IP

目录 DNS 查询服务器的基本流程DNS 采用 TCP 还是 UDP,为什么?默认使用 UDP 的原因需要使用 TCP 的场景?总结 DNS 劫持是什么?解决办法?浏览器输入一个 URL 到显示器显示的过程?URL 解析TCP 连接HTTP 请求页…

探究DeepSeek R1与OpenAI模型文本相似度背后的秘密

摘要 一项由Copyleaks进行的新研究显示,DeepSeek R1生成的文本在风格上与OpenAI模型的相似度高达74.2%。这一发现引发了对DeepSeek训练数据来源和独特性的质疑。Copyleaks作为专业检测文本抄袭和AI生成内容的平台,其研究结果具有重要参考价值。此相似度揭…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.3案例:电商订单日志每秒10万条写入优化

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch批量写入性能调优实战:2.2.3 案例:电商订单日志每秒10万条写入优化1. 原始架构与瓶颈分析1.1 初始集群配置1.2 性能瓶颈定位 2. 全链路…