C++里的异同点

文章目录

  • 1. 可以在构造函数和析构函数中调用虚函数吗?
  • 2. 类对象的内存模型(内存布局)
  • 3. 菱形继承问题(钻石问题)如何解决?
  • 4. 堆和栈内存区别
  • 5. static_cast和dynamic_cast异同
  • 6. 智能指针的实现机制
  • 7. 移动构造函数和拷贝构造函数区别
  • 8. 内联函数inline

1. 可以在构造函数和析构函数中调用虚函数吗?

  • 可以,但没有动态绑定的效果。
  • 因为当基类指针或引用指向子类对象,调用构造函数时,先构造父类,再构造子类。在构造父类时,由于子类还未被构造,无法下调子类的虚函数。同样,调用析构函数时,析构顺序和构造顺序相反,先析构子类。在析构父类时,由于子类已经被析构,所以也是无法触发多态。

2. 类对象的内存模型(内存布局)

  • 有虚函数时,虚表指针存放在对象的首地址处;接着,按继承顺序的数据成员声明顺序布局(虚表指针》父类数据成员》子类数据成员)。
  • 多继承时,有虚函数的父类会有自己的虚表,按照继承顺序的虚表指针和数据成员布局(父类A虚表指针》父类A数据成员》父类B虚表指针》父类B数据成员》子类数据成员)。另外,如果子类也有虚函数,就会在第一个虚表上增加该虚函数地址。
  • 菱形继承,且采用了虚继承。内存布局顺序:各个父类、子类、公共基类。(父类A虚表指针》父类A数据成员》父类B虚表指针》父类B数据成员》子类数据成员》公共基类虚表指针》公共基类数据成员)。另外,由于虚继承,各个父类不再拷贝公共基类的数据成员。

3. 菱形继承问题(钻石问题)如何解决?

  • 存在二义性问题,由于两个父类都会对公共基类的属性和方法进行拷贝,当子类访问公共基类的属性或方法时,不知道要访问哪个父类的属性或方法,导致编译错误
  • 解决:采用虚继承,即两个父类继承公共基类时用virtual修饰。这样保证只有一份公共基类的拷贝。

4. 堆和栈内存区别

  • 堆内存需要手动管理,可能会造成内存泄漏问题;栈内存是由系统自动管理。
  • 堆能分配的内存较大(32位系统下通常4G);栈能分配的内存较小(默认1M)。
  • 在堆中分配和释放内存会产生内存碎片;栈不会产生内存碎片。
  • 堆内存分配效率低;栈内存分配效率高。
  • 堆地址从低向上;栈地址从高向下。

5. static_cast和dynamic_cast异同

  • static_cast:用于基本数据类型间转换,能进行类层次间的向上和向下转换,但向下转换不安全,因为没有进行动态类型检查。
  • dynamic_cast:用于多态对象间转换,将基类指针或引用转换为子类指针或引用(也可以向上转换),从而访问子类特有的成员函数。注意 ,引用转型失败会抛异常”bad_cast“;指针转型失败会返回一个空指针,如果漏写检查代码(assert/if语句)会导致安全隐患
  • 二者都会做类型安全检查,但处理阶段不一样。static_cast在编译期进行类型检查,dynamic_cast在运行期进行类型检查。
  • dynamic_cast需要父类有虚函数,而static_cast不需要。

6. 智能指针的实现机制

  • 智能指针是为了解决内存泄漏问题,它可以自动释放内存空间。因为它本身是一个类,由析构函数释放内存空间。
  • unique_ptr:独占所指向的对象的所有权。底层使用了C++11的=delete,禁止直接构造和拷贝构造,确保了独一无二的特性。但是,可以使用移动语义来移动所有权。
  • shared_ptr:允许多个指针共享同一个对象的所有权。底层使用了引用计数机制,当引用计数为0时,会自动释放堆内存。
    • shared_ptr内存泄漏问题:shared_ptr相互引用会导致引用计数混乱,堆内存无法正确释放,造成内存泄漏。
    • 解决:使用weak_ptr打破循环引用,因为它不会增加引用计数
    • shared_ptr线程安全问题:shared_ptr的引用计数本身是安全且无锁,但它所指对象的读写则不是,因为shared_ptr有两个数据成员,读写操作不能原子化,所以shared_ptr不是线程安全。
    • 场景:多个线程读写同一个shared_ptr对象,需要加锁。
    • shared_ptr 具体实现
      • 构造函数:将指针指向该对象,引用计数置1;
      • 拷贝构造函数:将指针指向该对象,引用计数+1;
      • 赋值运算符:等号左边的shared_ptr引用计数-1,且若引用计数为0,还要释放指针所指对象的内存空间。等号右边的shared_ptr引用计数+1。

7. 移动构造函数和拷贝构造函数区别

  • 移动构造函数需要传递一个右值引用,不分配新内存,而是接管传递对象的内存,并在移动之后将源对象销毁。
  • 拷贝构造函数需要传递一个左值引用,可能会重新分配内存,性能更低。

8. 内联函数inline

  • 作用:让编译器在函数调用点上展开函数,可以避免函数调用的开销。
  • 场景:适用于简单且频繁调用的函数。
  • 缺点:
    • 可能造成代码膨胀,尤其是递归函数,导致可执行文件太大,造成大量内存开销。
    • 不方便调试
    • 每次修改内联函数的实现或调用内联函数的地方时,编译器重新生成大量的代码,增加编译时间

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

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

相关文章

无需劳师动众,让石油化工DCS集散控制系统轻松实现无线传输!

石油化工中,为了保证较高的可靠性和安全性,大量使用的是DCS集散控制系统。与FCS现场总线的“现场采集,转换为数字信号来集中传输”不同,DCS系统为了避免由于线缆断裂或者节点问题导致整个控制系统失灵,采用“分散传输,集中采集”的方式,即每个传感器通过4-20mA的模拟量通…

custom_evaluator.py

import numpy as np from pycocotools.cocoeval import COCOeval# 自定义COCOeval类,继承自COCOeval class CustomCOCOeval(COCOeval):# 重写computeIoU方法def computeIoU(self, imgId, catId):p self.paramsif p.useCats:gt self._gts[imgId, catId]dt self._d…

Linux——进程练习

1、使用进程知识点&#xff0c;尝试完成如下功能: 输入n&#xff0c; 动态生成n个子进程&#xff0c;并打印输出各自进程的pid号。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h>#include <sys/types.h>in…

Linux下创建Oracle数据库的实例

1.安装前准备 1.1.安装前准备一 安装前准备信息 数据库版本&#xff1a;Oracle19.16.0.0.0Linux版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo)主机名&#xff1a;ace-test-84IP&#xff1a;10.10.10.212SID&#xff1a;dcpfareintservice_name&#x…

电机应用相关名词介绍

1.电机转速 定义&#xff1a;电机转速指电机工作时旋转的速度&#xff0c;是衡量电机性能的重要指标之一。 单位&#xff1a; 每分钟转数&#xff08;RPM&#xff09;&#xff1a;即Revolutions Per Minute&#xff0c;表示电机每分钟旋转的圈数。 每秒转数&#xff08;RPS…

【小工具】Unity批量删除物体上引用丢失的脚本

介绍 Unity批量删除物体上引用丢失的脚本 使用场景 当在外部导入资源时会造成物体上挂载的脚本引用丢失&#xff0c;一个个删除比较麻烦&#xff0c;可以借用这个工具快速实现 工具原理 继承EditorWindow绘制一个自定义的编辑器窗口 加载Assets目录下所有预制体 获取其所有…

畜牧机械5G智能制造工厂物联数字孪生平台,推进制造业数字化转型

畜牧机械5G智能制造工厂物联数字孪生平台&#xff0c;推进制造业数字化转型。畜牧机械5G智能制造工厂物联数字孪生平台&#xff0c;是近年来制造业数字化转型的杰出代表。工业物联数字孪生平台平台集成了物联网、大数据、云计算和人工智能等先进技术&#xff0c;通过高速、低延…

elk对于集群实例的日志的整合-基于filebeat+k8s采集日志

说明&#xff1a;基于filebeat采集日志 概述&#xff1a; 在Kubernetes环境中&#xff0c;Filebeat不需要和业务服务部署在同一个容器中。通常的做法是将Filebeat作为一个DaemonSet部署在集群中&#xff0c;这样它可以在每个节点上运行一个实例&#xff0c;并从所有容器中收集…

Ubuntu下TensorRT与trtexec工具的安装

新版&#xff08;这里测试的是10.1版&#xff09;的onnx转tensorrt engine工具trtexec已经集成在TensorRT中&#xff0c;不需要额外单独安装。 教程来源于此网页&#xff1a;https://medium.com/moshiur.faisal01/install-tensorrt-with-command-line-wrapper-trtexec-on-unun…

redis需要知道的点

目录 一、为什么要用缓存 二、使用 Redis有哪些好处 三、什么是 redis&#xff1f; 四、redis和memcached区别 五、为什么redis单线程模型效率也能那么高 六、redis的线程模型 七、redis 6.0 引入多线程 八、为什么Redis需要把所有数据放到内存中&#xff1f; 九、Red…

cad由于找不到mfc140u.dll的解决方法,彻底解决mfc140u.dll丢失问题

在计算机辅助设计&#xff08;CAD&#xff09;的时候&#xff0c;我们可能会遇到各种错误和问题。其中&#xff0c;“CAD由于找不到mfc140u.dll&#xff0c;无法继续执行代码”的错误提示。这个问题可能会导致CAD无法启动运行&#xff0c;因此&#xff0c;我希望通过分享我的经…

site 搜索技巧 指定网站 屏蔽网站

指定某网站内容&#xff1a;site:xxx 屏蔽某网站内容&#xff1a;-site:xxx 例如&#xff1a;搜 springboot项目demo&#xff0c;你想只搜csdn&#xff0c;屏蔽掉博客园&#xff0c;51cto&#xff0c;等&#xff0c;在输入框中输入如下&#xff1a; springboot项目demo site:c…

基于elastic stack搭建的ELK系统资源占用预估

1、ES 1.1 内存&#xff1a;ES非常消耗内存&#xff0c;不是JVM用到的内存,而是机器的物理内存,ES在运行期间对JVM Heap(堆内存)的需求较小 实践建议: 数据量过百万,建议单台服务器的内存至少要有16GB;数据量过亿,建议单台服务器的内存至少要有64GB 1.2 CPU&#xff1a;ES集…

计算机网络之数据通信原理(下)

上一讲内容&#xff1a;数据传输方式、数据传输形式、传输差错处理、常用差错检测方法 数据通信过程中&#xff0c;一个很重要的问题就是如何控制数据的传输&#xff0c;就涉及到了传输控制规程&#xff08;协议&#xff09; 下面介绍两种&#xff1a; ①BSC&#xff1a;面向…

鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段一

一、鸿蒙开发环境搭建 DevEco Studio安装 下载 访问官网&#xff1a;https://developer.huawei.com/consumer/cn/deveco-studio/选择操作系统版本后并注册登录华为账号既可下载安装包 安装 建议&#xff1a;软件和依赖安装目录不要使用中文字符软件安装包下载完成后&#xff0…

GGUF模型转换入门

一、定义 1 定义 2 案例 二、实现 定义 GGUF是一种大模型文件格式&#xff0c;由开发者Georgi Gerganov提出。 这是一种针对大规模机器学习模型设计的二进制格式文件规范。它的主要优势在于能够将原始的大模型预训练结果经过特定优化后转换成这种格式&#xff0c;从而可以更…

鸿蒙Harmony开发实战案例:使用OpenGL绘制3D图形

XComponent控件常用于相机预览流的显示和游戏画面的绘制,在OpenHarmony上&#xff0c;可以配合Native Window创建OpenGL开发环境&#xff0c;并最终将OpenGL绘制的图形显示到XComponent控件。本文将采用"Native C"模板&#xff0c;调用OpenGL ES图形库绘制3D图形&…

python之__call__函数介绍

Python 中的 __call__ 方法是一种特殊的方法,它允许对象像函数一样被调用。当你创建一个对象并使用括号 () 调用它时,Python 会自动调用这个对象的 __call__ 方法。 1. 基本用法 下面是一个简单的例子: class MyClass:def __init__(self, value):self.value valued…

yaml文件的介绍-K8S

yaml 文件是我们使用K8S管理应用程序常用的部署方式&#xff0c;它主要是通过一系列键值对组成&#xff0c;键和值使用冒号和空格分隔。以下是对yaml的介绍 首先我们可以使用命令生成一个简单的YAML模版文件 Kubectl run nginx-pod –imagenginx:latest –port80 –dry-runcli…

使用FRP 0.58版本进行内网穿透的详细教程

什么是FRP&#xff1f; FRP&#xff08;Fast Reverse Proxy&#xff09;是一款高性能的反向代理应用&#xff0c;主要用于内网穿透。通过FRP&#xff0c;您可以将内网服务暴露给外网用户&#xff0c;无需进行复杂的网络配置。 准备工作 服务器&#xff1a;一台具备公网IP的服…