C++ 知识点(长期更新)
C++ 知识点
- C/C++
- 1. `cin`, `cin.get()`, `getchar()`, `getline()`, 和 `cin.getline()`的区别。
- 2. 有关 cin >>
- 3. 定义和声明的区别
- 4. `union`、`struct`和`class`的区别
- 5. 深拷贝 vs 浅拷贝
- 6. new 和 malloc 的区别
- 7. 被free回收的内存是立即返还给操作系统吗?为什么
- 8. C++的调用惯例
- 9. delete 和 delete []
- 10. 子类析构时要调用父类的析构函数吗?
- 11. 纯虚函数(抽象类)
- 12. 静态绑定和动态绑定的介绍
- 13. 动态绑定是怎么实现的?
- 14. 虚函数表、虚函数指针是什么?
- 15. 虚函数的实现机制(内存分布)
- 16. 一个类一个虚函数表还是一个对象一个虚函数表?
- 17. 虚函数表指针是怎么找到实现的哪个虚函数的?
- 18. 虚函数表存在哪里?
- 19. 虚函数表指针是什么时候加载的?
- 20. 模板的用法与适用场景实现原理
- 21 多态、虚函数、纯虚函数
- 22. 继承机制中对象之间是如何转换的?
- 23. 如何实现只能动态分配类的对象?只能静态分配呢?
C/C++
1. cin, cin.get(), getchar(), getline(), 和 cin.getline()的区别。
cin通常用于读取单个单词或基本类型数据,遇到空白字符会停止。cin.get()和getchar()用于读取单个字符,包括空白字符,但getchar()不是cin的成员函数。getline()和cin.getline()用于读取整行数据,包括空白字符,直到换行符。getline()可以读取到string对象中,而cin.getline()需要指定字符数组缓冲区。cin.getline()会从输入流中取出分隔符,而getline()则不会。cin和cin.get()在读取失败时,可能会设置错误标志,而getchar()不会影响cin的错误状态。
#include <iostream>
#include <string>int main() {// 使用 cin 读取一个单词// 当你输入一个单词并按回车时,cin只会读取直到第一个空白字符之前的文本,所以如果输入Hello World,只会输出Hello。std::string word;std::cout << "Enter a word: ";std::cin >> word;std::cout << "You entered: " << word << std::endl;// 清除输入缓冲区中的剩余字符(包括换行符)std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');// 使用 cin.get() 读取一个字符// cin.get()会读取输入流中的下一个字符,即使它是空白字符。如果在上一个例子中直接按回车,它会读取换行符。char ch;std::cout << "Enter a character: ";ch = std::cin.get();std::cout << "You entered: " << ch << std::endl;// 使用 getchar() 读取一个字符// getchar()与cin.get()类似,但它是从标准输入读取字符,不会影响cin的状态。std::cout << "Enter another character: ";ch = getchar();std::cout << "You entered: " << ch << std::endl;// 清除输入缓冲区中的剩余字符(包括换行符)std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');// 使用 getline() 读取整行// getline()读取整行,包括空白字符,直到遇到换行符。如果你输入This is a line,它会输出整行。std::string line;std::cout << "Enter a line of text: ";getline(std::cin, line);std::cout << "You entered: " << line << std::endl;// 使用 cin.getline() 读取整行// cin.getline()读取整行,包括空白字符,但它需要指定一个字符数组来存储输入的字符串char buffer[256];std::cout << "Enter another line of text: ";std::cin.getline(buffer, sizeof(buffer));std::cout << "You entered: " << buffer << std::endl;return 0;
}
2. 有关 cin >>
// cin >> 的函数原型:
std::istream& operator>>(std::istream& in, int& value);
cin >>实际上调用cin的成员函数operator>>(int& value) ,cin 是 std::istream 类型的对象
// 链式调用的原理:返回类型为std::istream&
cin >> n >> m >> k;// 实际上是:
cin >> n;
cin >> m;
cin >> k;
3. 定义和声明的区别
声明(Declaration):
- 声明告诉编译器一个名字的存在以及它的一些属性,但不分配存储空间。
- 声明可以多次出现,但定义只能出现一次。
- 声明可以出现在多个文件中,而定义必须唯一。
- 对于函数,声明通常包含了函数的返回类型、名称和参数类型(即函数原型)。
- 对于变量,声明包含了变量的类型和名称,但不包括初始值。
- 声明可以使用
extern关键字来指定变量或函数在其他地方定义。
定义(Definition):
- 定义除了具有声明的所有属性外,还分配了存储空间(对于变量)或指定了函数的实现(对于函数)。
- 定义在程序中只能出现一次,因为它指定了具体的实现细节。
- 对于变量,定义包含了变量的类型、名称和初始值(如果有的话)。
- 对于函数,定义包含了函数体,即函数执行的具体代码。
extern int var; // 声明一个变量
void function(int param); // 声明一个函数int globalVar = 10; // 定义一个全局变量,并初始化
void function(int param) { // 定义一个函数// 函数体
}
// question int x; 是个定义还是声明?
// 有extern是声明,没有extern是声明及定义
4. union、struct和class的区别
union、struct和class都用于自定义数据类型 ,union 不可拥有静态成员及虚函数且不可继承,struct和class的主要区别在于默认的访问权限。
Union
union可以存储不同的数据类型,但在同一时刻只能存储其中一个类型的值。- 它的成员共享同一块内存空间,大小由最大的成员决定。
- 在同一时间只能访问一个成员,因为所有成员共享内存。
Struct
struct(结构体)是一种用于封装不同数据类型的数据项的集合。- 默认情况下,
struct的成员是公有的(public)。 struct通常用于简单的数据聚合,不涉及复杂的操作或继承。
Class
class是C++面向对象编程的核心,用于定义对象和它们的操作。- 默认情况下,
class的成员是私有的(private)。 class支持继承、多态、封装和抽象等面向对象的概念。
5. 深拷贝 vs 浅拷贝
浅拷贝在资源管理及数据独立性上有很大问题!会出现未定义行为
浅拷贝就是将对象的指针进行简单的复制,原对象和副本指向的是相同的资源。
深拷贝新开辟一块空间,将原对象的资源复制到新的空间中,并返回该空间的地址。
深拷贝可以避免重复释放和写冲突。例如使用浅拷贝的对象进行释放后,对 原对象的释放会导致内存泄漏或程序崩溃。
在C++中,如果不显式定义拷贝构造函数和赋值运算符,编译器会为类自动生成默认的浅拷贝版本。
// 深拷贝
class MyString {
public:// 构造函数MyString(const char* str = nullptr) {if (str) {size_ = strlen(str);data_ = new char[size_ + 1];strcpy(data_, str);} else {size_ = 0;data_ = new char[1];*data_ = '\0';}}// 拷贝构造函数(深拷贝)MyString(const MyString& other) {size_ = other.size_;data_ = new char[size_ + 1];strcpy(data_, other.data_);}// 拷贝赋值运算符重载(深拷贝)MyString& operator=(const MyString& other) {if (this != &other) {delete[] data_;size_ = other.size_;data_ = new char[size_ + 1];strcpy(data_, other.data_);}return *this;}// 析构函数~MyString() {delete[] data_;}
private:char* data_;size_t size_;
};
6. new 和 malloc 的区别
new/delete | malloc/free | |
|---|---|---|
| 属性 | 运算符重载 | 库函数 |
| 参数 | 无须指定内存块的大小,编译器会根据类型信息自行计算 | 要显式地指出所需内存的大小 |
| 返回值 | 返回对象类型的指针 | 返回 void * ,需要强转 |
| 自定义? | 可以做自定义类型对象的构造/析构函数 | 无法做自定义类型对象构造/析构工作 |
| 重载? | 允许重载 | 没有重载机制 |
| 异常处理 | 抛出std::bad_alloc异常 | 失败为 NULL |
// question:有了malloc/free,C++中为什么还需要new/delete?
// 对非基本数据类型的对象使用的时候,对象创建的时候还需要执行构造函数,销毁的时候要执行析构函数,malloc/free无法满足// 实际上,new/detele 是封装malloc/free 实现的
class Example {......static void* operator new(std::size_t size) {// 调用malloc 分配内存// 调用构造函数// 返回指针}
}
7. 被free回收的内存是立即返还给操作系统吗?为什么
并不是,返回给堆
8. C++的调用惯例
C++的调用惯例是编译器在执行函数调用时的规则,它定义了参数传递的方式、返回值的处理、寄存器的使用等。参数从右到左依次压入堆栈,函数调用者负责清理堆栈。
9. delete 和 delete []
delete和delete []都是用于释放动态分配内存的运算符,但它们之间存在一些关键的区别。当delete []操作符用于数组时, 它为每个数组元素调用析构函数,然后调用 operator delete 来释放内存。
-
释放对象 or 数组:
delete用于释放单个对象所占用的内存。delete []用于释放数组对象所占用的内存。
-
内存释放方式:
delete释放单个对象时,会调用对象的析构函数。delete []释放数组对象时,会调用数组对象的析构函数,并且会自动调用数组中每个元素的析构函数。
class Test { public:Test() {cout << "构造啦" << endl;}~Test() {cout << "析构啦" << endl;}};int main() {Test* array = new Test[4];delete[] array;return 0; } // output 构造啦 构造啦 构造啦 构造啦 析构啦 析构啦 析构啦 析构啦 -
数组内存释放:
delete不适用于数组,如果尝试使用delete释放数组,只会调用一次析构函数。delete []用于释放数组时,会释放整个数组所占用的内存,包括数组中的每个元素。
class Test { public:Test() {cout << "构造啦" << endl;}~Test() {cout << "析构啦" << endl;} };int main() {Test* array = new Test[4];delete array;return 0; } // output 构造啦 构造啦 构造啦 构造啦 析构啦
10. 子类析构时要调用父类的析构函数吗?
构造顺序:父类的构造函数->子类的构造函数
析构顺序:子类的析构函数->父类的析构函数
当一个派生类对象被销毁时,首先会调用派生类的析构函数,然后自动调用基类的析构函数(无论析构函数是否是虚函数)。这样可以确保基类和派生类的资源都能被正确地释放。
class Test {
public:Test() {cout << 相关文章:
C++ 知识点(长期更新)
C++ 知识点 C/C++1. `cin`, `cin.get()`, `getchar()`, `getline()`, 和 `cin.getline()`的区别。2. 有关 cin >>3. 定义和声明的区别4. `union`、`struct`和`class`的区别5. 深拷贝 vs 浅拷贝6. new 和 malloc 的区别7. 被free回收的内存是立即返还给操作系统吗?为什么…...
Spring AI + 通义千问 入门学习
Spring AI 通义千问 入门学习 文章目录 Spring AI 通义千问 入门学习一,开发环境配置二,项目搭建2.1 pom文件2.2 配置文件 三,AI使用3.1 对话问答3.1.1 普通方式3.1.2 流方式 3.2 文字生成图片 最近AI很火,而Spring也出了Spring…...
38.【C语言】指针(重难点)(C)
目录: 8.const 修饰指针 *修饰普通变量 *修饰指针变量 9.指针运算 *指针或-整数 *指针-指针 *指针关系运算 往期推荐 承接上篇37.【C语言】指针(重难点)(B) 8.const 修饰指针 const 全称 constant adj.不变的 *修饰普通变量 #…...
Vue-05.指令-v-for
v-for 列表渲染,遍历容器的元素或者对象的属性 v-for“列表元素名 in 列表名” <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wi…...
自动驾驶的一些大白话讲解
无人驾驶牛逼吗?我来帮你祛魅【原理缺陷解析】_哔哩哔哩_bilibili 5分钟讲明白自动驾驶端到端,解释为什么华为智驾并不是遥遥领先 到底什么是端到端自动驾驶系统?为何我会说这是智能驾驶的弯道超车机会?我希望今天用5分钟的时间&…...
Python学习笔记--参数
目录 实参与形参 不定长参数 拆分参数列表 返回值 实参与形参 1. 定义函数时,带默认值的形参必须放在不带默认值的形参后面 下面程序的输出结果是( )。 def StudentInfo(country中国,name): print(%s,%s%(name,country)…...
刷题——大数加法
大数加法_牛客题霸_牛客网 string solve(string s, string t) {if(s.size() < t.size()) return solve(t, s);reverse(s.begin(), s.end());reverse(t.begin(), t.end());string ans;int d 0;//进位制for(int i0; i < s.size(); i){d s[i] - 0;//取得数字值if(i < …...
Pytorch人体姿态骨架生成图像
ControlNet是一个稳定扩散模型,可以复制构图和人体姿势。ControlNet解决了生成想要的确切姿势困难的问题。 Human Pose使用OpenPose检测关键点,如头部、肩膀、手的位置等。它适用于复制人类姿势,但不适用于其他细节,如服装、发型和…...
前端面试常考的HTML标签知识!!!
语义标签 标签名语义描述header网页头部网页的主要头部区域nav网页导航网页的导航链接区域footer网页底部网页的底部区域aside网页侧边栏网页的侧边栏区域section网页区块网页的独立区块 | article | 网页文章 | 网页的独立文章区域 | 字符实体 作用:在网页中显…...
Oracle触发器
Oracle触发器就是特定事件发生时自动执行的存储过程。 触发器基本使用 基本语法: create [or replace] trigger 触发器名称 alter | before | instead of [insert] [[or] update [of 列1,列2,...]] [[or] delete] on 表名 [referencing {OLD [as] old / NEW [as]…...
GPT-5:未来已来,我们如何共舞于智能新纪元?
GPT-5:未来已来,我们如何共舞于智能新纪元? 在科技日新月异的今天,人工智能(AI)的每一次飞跃都深刻地改变着人类社会的面貌。从AlphaGo击败围棋世界冠军,到GPT系列模型引领自然语言处理&#x…...
2024年6月 青少年机器人技术等级考试理论综合试卷(五级)
202406 青少年等级考试机器人理论真题五级 第 1 题 ESP32 for Arduino,通过引脚2读取按键开关的返回值,电路如下图所示,程序pinMode(2, mode);中,参数mode的值是?( ) A:INPUT B&…...
【Go】 HTTP编程3-路由httprouter
HttpRouter httprouter httprouter是第三方的库,不是go的标准库,使用命令 go get -u github.com/julienschmidt/httprouter ,下载该模块,-u表示如果已经下载但更新到最新版本Router 实现了http.Handler接口,为各种 re…...
Spring Boot 整合 SA-Token 使用详解
Spring Boot 整合 SA-Token 使用详解 在现代Web开发中,用户认证与授权是构建安全应用的基础。SA-Token是一个轻量级的Java权限认证框架,它以其简洁的API设计、高效的执行效率以及丰富的功能特性,成为了众多开发者在Spring Boot项目中实现用户…...
1.3 C 语言入门实战:从 Hello World 到基础语法解析
目录 1 程序的作用 2 初识 Hello World 2.1 新建项目 2.2 程序解释 3 printf 的作用 4 注释及其注意事项 4.1 单行注释 4.2 多行注释 4.3 嵌套错误 5 项目在磁盘上的位置 1 程序的作用 如下图所示,我们编写了一个可以做加法的程序,我们给程序…...
一文读懂什么是Go语言goroutine
1. 进程、线程和协程的区别 进程: 进程是具有一定独立功能的程序,进程是系统资源分配和调度的最小单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换…...
计算机毕业设计 农家乐管理平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
Spring Boot优缺点
Spring Boot 是一款用于简化Spring应用开发的框架,它集成了大量常用的框架和工具,大大简化了Spring项目的配置和部署。下面是Spring Boot的优缺点: 优点: 简化配置:Spring Boot自动配置功能可以根据应用的依赖自动配…...
Android Studio中创建apk签名文件
本文以macOS中Android Studio 2021.1.1版本为例介绍创建apk签名文件的操作步骤: 1.启动Android Studio,并打开一个Android项目。 2.依次点击菜单:Build -> Generate Signed Bundle / APK...。 3.在弹出的"Generate Signed Bundle or …...
CRC32 JAVA C#实现
项目中用到CRC32进行校验得地方,需要用到C#和java进行对比: 一、C#实现: class CRC32Cls { protected ulong[] Crc32Table; //生成CRC32码表 public void GetCRC32Table() { ulong Crc; …...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
