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

【C++】总结2

文章目录

  • 1.final和override关键字
  • 2.extern "C"的用法
  • 3.野指针和垂悬指针(悬空指针)
  • 4.指针指向的内存被释放是什么意思
  • 5.C和C++的类型安全
  • 6.C++中的重载、重写(覆盖)和隐藏的区别

1.final和override关键字

final和override是C++11引入的关键字,用于在类的继承和虚函数重写中进行特定的语义声明

  • final

    final关键字用于修饰类、成员函数或虚函数,表示它们是最终版本,不允许被继承、重写或覆盖

    用于修饰类时,表示该类的最终类,不能被其他类继承

    用于修饰成员函数时,表示该成员函数是最终版本,不能被子类的同名函数重写或覆盖。

  class Base {public:virtual void foo() final; // 声明foo()是最终版本,不允许子类重写};class Derived : public Base {public:// 试图重写foo(),但由于在Base中声明为final,将会产生编译错误// void foo() override; // 错误,不能重写final函数};
  • override

    override关键字用于修饰派生类中覆盖基类的虚函数,用于明确标识该函数是对基类虚函数的覆盖实现,提高代码的可读性和安全性

    使用override关键字可以确保子类中的虚函数命名和基类中的虚函数一致,防止由于命名不一致而导致的意外。

  class Base {public:virtual void foo();};class Derived : public Base {public:void foo() override; // 明确标识对基类虚函数foo()的覆盖};

总之:final关键字用于阻止类或成员函数的继承或重写,而override关键字用于明确标识派生类中对基类虚函数的覆盖实现。这两个关键字都提高了代码的安全性和可读性,并在面向对象编程中起到重要的作用。

2.extern "C"的用法

  • extern “C” 是C++中用于处理C语言和C++语言混合编程的关键字,在C++中,有时候需要与C语言的代码进行链接,或者在C++中调用C语言编写的函数,此时就可以使用extern “C” 来声明C语言的函数接口

  • 当使用extern “C” 声明函数时,C++编译器会按照C语言的命名规则来处理该规则,这样可以确保C++和C的函数名在链接时保持一致,避免了由于C++的函数重载等特性导致的函数名修饰不一致的问题

  • 假设有以下 C 语言的头文件 functions.h

  // functions.h#ifndef FUNCTIONS_H#define FUNCTIONS_Hint add(int a, int b);#endif // FUNCTIONS_H
  • 对应的 C 语言源文件 functions.c 实现了该头文件中的函数:
  // functions.c#include "functions.h"int add(int a, int b) {return a + b;}
  • 现在我们在 C++ 代码中想要调用 add 函数,可以在 C++ 文件中这样声明:
  // main.cpp#include <iostream>#include "functions.h"extern "C" {#include "functions.h" // 使用 extern "C" 包裹 include 指令}int main() {int result = add(5, 10);std::cout << "Result: " << result << std::endl;return 0;}
  • 总结:extern "C" 用于在 C++ 中处理 C 语言的函数接口,保证函数名在链接时的一致性,从而实现 C 和 C++ 的混合编程。这在与 C 语言编写的库或代码进行交互时非常有用。

3.野指针和垂悬指针(悬空指针)

  • 野指针是指指针指向的内存地址是无效的,即指针没有被正确初始化,或者指针指向的内存已经被释放,但指针本身还保留着原来的地址。

    当我们使用野指针时,由于其指向的内存可能已经被其他程序或系统回收,所以访问该指针指向的内存会导致不可预测的行为,可能会导致程序崩溃或产生错误的结果

    野指针的产生通常是由于以下原因:

    • 1.未初始化指针:指针变量在定义后没有被正确初始化,它的值是随机的,可能指向任意内存地址
    • 指针指向已释放的内存:在使用delete或free释放内存后,没有将指针置为nullptr
  int* ptr = new int;delete ptr; // 释放内存后,ptr 成为野指针,应该将 ptr 置为 nullptrptr = nullptr;
  • 指针误用:指针被错误的修改,导致它指向了无效的内存地址
  int arr[5] = {1, 2, 3, 4, 5};int* ptr = &arr[0];ptr += 10; // ptr被错误地修改,指向了不属于arr的内存地址,ptr成为野指针

要避免使用野指针,我们要养成良好的编程习惯,确保指针在定义后都被正确初始化,并在释放指针指向的内存后,立即将指针置为nullptr。同时,不要随意修改指针的值,以防止野指针的产生

  • 垂悬指针是指指针指向的内存已经被释放或释放后没有及时置空,导致指针的值仍然是之前指向的地址,但该地址的内容可能已经无效。当我们使用垂悬指针时,由于其指向的内存已经无效,访问该指针指向的内存会导致未定义行为,可能会产生不可预测的结果。

    垂悬指针通常是由于以下原因产生:

    • 释放后未置空:在使用 deletefree 释放内存后,没有将指针置为 nullptr
  int* ptr = new int;delete ptr; // 释放内存后,ptr 成为垂悬指针,应该将 ptr 置为 nullptrptr = nullptr;
    • 引用悬挂:当指针指向一个引用,而该引用的生命周期已经结束,指针就会成为垂悬指针。
  int a = 10;int& ref = a;int* ptr = &ref; // ptr 指向引用 ref,如果在之后 ref 的生命周期结束,ptr 就会成为垂悬指针
    • 函数返回局部变量地址:在函数内部定义了一个局部变量,并返回其地址,但在函数结束后,该局部变量的内存已经被释放。

要避免使用垂悬指针,我们应该养成良好的编程习惯,在释放指针指向的内存后,立即将指针置为 nullptr。同时,在返回局部变量的指针时,应该确保返回的是有效的动态内存分配(堆内存)或者静态存储区(全局变量或静态变量)的地址。

4.指针指向的内存被释放是什么意思

释放内存意味着该内存不再属于当前程序,系统可以重新分配给其他程序使用。

5.C和C++的类型安全

  • 类型安全是指编程语言或程序设计中的一种属性,确保在程序执行过程中不会发生不合法或未定义的类型操作,类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域。类型安全保证了以下几点:

    • 类型检查:在编译或运行时,编程语言会对类型进行检查,防止不同类型之间的非法操作
    • 类型转换的明确性:在进行类型转换时,必须明确指定,避免隐式的不明确转换,从而降低类型错误的概率
    • 类型兼容性:确保只有合法的类型转换才能进行,防止发生未定义行为或错误的结果
    • 内存安全性:防止越界访问、空指针引用等导致的内存错误,从而提高程序的稳定性和安全性
  • C的类型安全性:

    C是一种弱类型语言,类型的转换相对灵活,可以进行隐式类型转化,这使得C中存在潜在的类型错误和未定义行为;C编译器在类型检查方面较弱,无法在编译时完全捕获所有类型错误,可能会导致在运行时出现错误

    以下是常见的例子

    • printf格式输出

      int main() {printf("int类型输出:%d\n", 10);printf("float类型输出:%f\n", 10);return 0;
      }
      

      执行结果:

      int类型输出:10
      float类型输出:0.000000
      
    • malloc函数的返回值

      malloc是C语言中用来进行内存分配的函数,它的返回类型是void* ,我们经常对结果进行类型转换, char* pstr=(char* )malloc(100*sizeof(char)),我们进行了显式类型转换,将void *类型转换为了char * 类型,sizeof的参数类型和显式转换的类型匹配的话,就没什么问题,但是如果不匹配,就很可能带来一些问题,如int * pstr=(int * )malloc(100 * sizeof(char)),而这样的转换C并不会提示错误。

  • C++的类型安全性

    C++是一种静态类型语言,类型检查在编译时进行,所有类型的转换必须显式指定(除了一些隐式类型转换,如派生类向基类的指针转换)

    C++ 提供了更强大的类型系统,包括强制类型转换(static_castdynamic_castreinterpret_castconst_cast)来明确指定类型转换,以及运算符重载来定义特定类型之间的操作。

6.C++中的重载、重写(覆盖)和隐藏的区别

  • 重载

    重载是指在同一个作用域内,函数名相同但参数列表不同的情况下,可以定义多个具有相同函数名但参数个数或类型不同的函数。

    重载函数可以根据不同的参数来执行相似的操作,提高代码的复用性和可读性

    重载函数在编译时通过参数个数、类型和顺序来决定调用哪个函数

  class Math {public:int add(int a, int b);double add(double a, double b);};
  • 重写/覆盖(override)

    重写是指派生类重新定义基类中的虚函数

    重写虚函数允许子类为基类的虚函数提供自己的实现,从而实现多态性

    重写发生在类之间的继承关系中,子类函数与父类函数具有相同的函数名、参数列表和返回类型,并且基类函数必须声明为虚函数

  class Shape {public:virtual void draw() {std::cout << "Drawing a shape." << std::endl;}};class Circle : public Shape {public:void draw() override {std::cout << "Drawing a circle." << std::endl;}};
  • 重载和重写的区别:

    • 重写是父类和子类之间的垂直关系,重载是不同函数之间的水平关系
    • 重写要求参数列表相同,重载则要求参数列表不同,返回值不要求
    • 重写关系中,调用方法根据对象类型决定,重载根据调用时实参与形参的对应关系来选择函数体
  • 隐藏

    隐藏是指在派生类中定义了一个与基类中同名但不具有虚函数特性的函数,这样它就会隐藏基类中的同名函数,包括以下情况:

    • 两个函数参数相同,但是基类函数不是虚函数。如果基类函数是虚函数,则就是重写了。
  //父类class A{public:void fun(int a){cout << "A中的fun函数" << endl;}};//子类class B : public A{public://隐藏父类的fun函数void fun(int a){cout << "B中的fun函数" << endl;}};int main(){B b;b.fun(2); //调用的是B中的fun函数b.A::fun(2); //调用A中fun函数return 0;}
  • 两个函数参数不同,则无论基类函数是否是虚函数,都会被隐藏。和重载的区别在于两个函数不在同一个类中。
  //父类class A {public:virtual void fun(int a) {cout << "A中的fun函数" << endl;}};//子类class B : public A {public://隐藏父类的fun函数virtual void fun(char* a) {cout << "A中的fun函数" << endl;}};int main() {B b;b.fun(2); //报错,调用的是B中的fun函数,参数类型不对b.A::fun(2); //调用A中fun函数return 0;}
  • 基类指针指向派生类对象时,基类指针可以直接调用到派生类的覆盖函数,也可以通过 :: 调用基类被覆盖的虚函数;而基类指针只能调用基类的被隐藏函数,无法识别派生类中的隐藏函数。

相关文章:

【C++】总结2

文章目录 1.final和override关键字2.extern "C"的用法3.野指针和垂悬指针(悬空指针)4.指针指向的内存被释放是什么意思5.C和C的类型安全6.C中的重载、重写&#xff08;覆盖&#xff09;和隐藏的区别 1.final和override关键字 final和override是C11引入的关键字&…...

vue2项目中使用svg图标

在开发项目的时候经常会用到svg矢量图,而且我们使用SVG以后&#xff0c;页面上加载的不再是图片资源, 这对页面性能来说是个很大的提升&#xff0c;而且我们SVG文件比img要小的很多&#xff0c;放在项目中几乎不占用资源。 1、安装SVG依赖插件并配置加载器和路径 npm instal…...

阿里云盘自动每日签到无需部署无需服务器(仅限学习交流使用)

一、前言 阿里云盘自动每日签到&#xff0c;无需部署&#xff0c;无需服务器 执行思路&#xff1a;使用金山文档的每日定时任务&#xff0c;执行阿里云盘签到接口。 二、效果展示&#xff1a; 三、步骤&#xff1a; 1、进入金山文档网页版 金山文档官网&#xff1a;https:…...

Blazor前后端框架Known-V1.2.7

V1.2.7 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazor…...

工业边缘计算为什么?

在工厂环境中使用边缘计算并不新鲜。可编程逻辑控制器&#xff08;PLC&#xff09;、微控制器、服务器和PC进行本地数据处理&#xff0c;甚至是微型数据中心都是边缘技术&#xff0c;已经在工厂系统中存在了几十年。在车间里看到的看板系统&#xff0c;打卡系统&#xff0c;历史…...

Training-Time-Friendly Network for Real-Time Object Detection 论文学习

1. 解决了什么问题&#xff1f; 目前的目标检测器很少能做到快速训练、快速推理&#xff0c;并同时保持准确率。直觉上&#xff0c;推理越快的检测器应该训练也很快&#xff0c;但大多数的实时检测器反而需要更长的训练时间。准确率高的检测器大致可分为两类&#xff1a;推理时…...

HTTP改HTTPS

tomcat中http协议改https 第一步&#xff0c;配置server.xml <?xml version"1.0" encoding"UTF-8"?> <Server port"8005" shutdown"SHUTDOWN"><Listener className"org.apache.catalina.startup.VersionLogger…...

网络层中一些零碎且易忘的知识点

异构网络&#xff1a;指传输介质、数据编码方式、链路控制协议以及数据单元格式和转发机制不同&#xff0c;异构即物理层和数据链路层均不同RIP、OSPF、BGP分别是哪一层的协议&#xff1a; -RIPOSPFBGP所属层次应用层网络层应用层封装在什么协议中UDPIPTCP 一个主机可以有多个I…...

【RabbitMQ】之高可用集群搭建

目录 一、RabbitMQ 集群原理 1、默认集群原理2、镜像集群原理3、负载均衡方案 二、RabbitMQ 高可用集群搭建 1、RabbitMQ 集群搭建2、配置镜像队列3、HAProxy 环境搭建4、Keepalived 环境搭建 一、RabbitMQ 集群简介 1、默认集群原理 3-1、RabbitMQ 集群简介 单台 RabbitM…...

【node.js】01-fs读写文件内容

目录 一、fs.readFile() 读取文件内容 二、fs.writeFile() 向指定的文件中写入内容 案例&#xff1a;整理txt 需求&#xff1a; 代码&#xff1a; 一、fs.readFile() 读取文件内容 代码&#xff1a; //导入fs模块&#xff0c;从来操作文件 const fs require(fs)// 2.调…...

GitHub仓库如何使用

核心&#xff1a;GitHub仓库如何使用 目录 1.创建仓库&#xff1a; 2.克隆仓库到本地&#xff1a; 3.添加、提交和推送更改&#xff1a; 4.分支管理&#xff1a; 5.拉取请求&#xff08;Pull Requests&#xff09;&#xff1a; 6.合并代码&#xff1a; 7.其他功能&…...

雪花算法,在分布式环境下实现高效的ID生成

其实雪花算法比较简单&#xff0c;可能称不上什么算法就是一种构造UID的方法。 点1&#xff1a;UID是一个long类型的41位时间戳&#xff0c;10位存储机器码&#xff0c;12位存储序列号。 点2&#xff1a;时间戳的单位是毫秒&#xff0c;可以同时链接1024台机器&#xff0c;每台…...

使用css 动画实现,水波纹的效果

每日鸡汤&#xff1a;每个你想要学习的瞬间都是未来的你向自己求救 需求&#xff0c;实现水波纹动画效果&#xff0c;要求中心一个圆点&#xff0c;然后有3个圈&#xff0c;一圈一圈的向里面缩小。 说实话我第一个想到了给3个圈设置不同的宽高&#xff0c;然后设置动画0-100%&a…...

Unity光照相关知识和实践 (烘焙光照,环境光设置,全局光照)

简介 本文将会通过一个简单的场景搭建&#xff0c;介绍如何使用烘焙光照以及相关的注意事项。另外还介绍了Unity内全局光照&#xff08;GI&#xff09;的知识和GI实际在游戏内的表现效果。 Unity关于光照相关的参考文档地址&#xff1a;https://docs.unity.cn/cn/current/Man…...

【设计模式——学习笔记】23种设计模式——适配器模式Adapter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 介绍生活中的案例基础介绍工作原理分类应用场景 案例类适配器模式例1介绍类图代码实现优缺点分析 例2类图代码实现 对象适配器模式&#xff08;常用方式&#xff09;例1介绍类图代码实现优缺点分析 例2代码实现 接口适配器模式介绍类图代码实现 登场角色类图类适配器模…...

Android Unit Test

一、测试基础知识 1.1 测试级别 测试金字塔&#xff08;如图 2 所示&#xff09;说明了应用应如何包含三类测试&#xff08;即小型、中型和大型测试&#xff09;&#xff1a; 小型测试是指单元测试&#xff0c;用于验证应用的行为&#xff0c;一次验证一个类。 中型测试是指…...

docker更新jenkins

下载文件 1、jenkins提示下载 2、官网下载jenkins官网 文件放服务器内 通过工具把jenkins.war放进服务器例如tmp 文件复制到docker的jenkins容器 docker cp 路径文件 容器id:/{后面不接内容为根路径} docker cp /tmp/jenkins.war 53dc1c71058a:/进入容器内 docker exec …...

一种新的基于区域的在线活动轮廓模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

【Docker】基于Dockerfile搭建LNMP架构

一、项目环境 公司在实际的生产环境中,需要使用Docker 技术在一台主机上创建LNMP服务并运行Wordpress网站平台。然后对此服务进行相关的性能调优和管理工作。 1. 环境配置 主机操作系统IP地址主要软件DockerCentOS 7.3 x86_64192.168.145.15Docker 19.03容器ip地址规划 ngin…...

爬虫003_pycharm的安装以及使用_以及python脚本模版设置---python工作笔记021

这里我们用ide,pycharm来编码,看一看如何下载 这里我们下载这个社区办,这个是免费的,个人版是收费的 然后勾选以后 安装以后我们来创建一个项目 这里可以选择python的解释器,选择右边的... 这里我们找到我们自己安装的python解释器...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...