作者 | 求求你们别学了 编辑 | 汽车人
原文链接:https://zhuanlan.zhihu.com/p/644283667
点击下方卡片,关注“自动驾驶之心”公众号
ADAS巨卷干货,即可获取
点击进入→自动驾驶之心【求职交流】技术交流群
本文只做学术分享,如有侵权,联系删文
汇总:class、封装、继承、多态、STL、指针和智能指针、static和const、其他零碎知识
参考:
作者:小王同学在积累 链接:https://www.zhihu.com/question/440248845/answer/1698042313
作者:二进制架构 链接:https://www.zhihu.com/people/binarch/posts?page=2
class:面向对象
struct和class有什么区别?
“在C++中,struct和class的唯一区别是默认的访问控制。struct默认的成员是public的,而class的默认成员是private的。
封装
C++面向对象的三大特性为:封装、继承、多态。C++认为万事万物都皆为对象,对象上有其属性和行为
什么是封装?
“将属性和行为作为一个整体,表现生活中的事物。将属性和行为加以权限控制
封装意义:
在设计类的时候,属性和行为写在一起,表现事物。
类在设计时,可以把属性和行为放在不同的权限下,加以控制。
访问权限有三种:public 公共权限;protected 保护权限;private 私有权限
继承
什么是继承?
“有些类与类之间存在特殊的关系,比如动物类和猫类。我们发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。这个时候我们就可以考虑利用继承的技术,减少重复代码
多态
什么是多态?
“多态分为两类:
静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
动态多态: 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
静态多态的函数地址早绑定 - 编译阶段确定函数地址
动态多态的函数地址晚绑定 - 运行阶段确定函数地址
多态需满足的条件:有继承关系,子类重写父类中的虚函数
多态使用条件:父类指针或引用指向子类对象
虚函数作用和意义?
“虚函数:虚函数是用于支持动态多态性的一种机制。如果一个类中声明了虚函数,那么在派生类中可以覆盖这个函数。在运行时,调用对象的虚函数会根据对象的实际类型来决定调用哪个函数。
什么是纯虚函数和抽象类?
“在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数。
纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;
当类中有了纯虚函数,这个类也称为抽象类。
抽象类特点:无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类。
STL
什么是STL?其创建目的是什么?
“软件界一直希望建立一种可重复利用的东西。C++的面向对象和泛型编程思想,目的就是复用性的提升。大多数情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作。为了建立数据结构和算法的一套标准,诞生了STL。
STL的基本概念以及组成?
“STL(Standard Template Library,标准模板库)。STL几乎所有的代码都采用了模板类或者模板函数。
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、分配器。
请简单介绍STL的六大组件。
“
容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
算法:各种常用的算法,如sort、find、copy、for_each等。
迭代器:扮演了容器与算法之间的胶合剂。可以通过迭代器来遍历容器
仿函数:是一个可执行的对象,类型重载了operator()()运算符。
适配器:适配器是一种设计模式。主要起到将不同的接口统一起来的作用。STL中的容器适配器如stack和queue,通过调用容器的接口,实现适配器所需的功能。
分配器:主要用于内存的分配与释放。一般容器都会自带默认分配器,很少会自己实现分配器。
什么是STL容器,常用的容器有哪些?
“容器:存放数据的地方。STL容器就是将运用最广泛的一些数据结构实现出来。常用的数据结构:数组、链表、树、栈、队列、集合、映射表 等。
请简单介绍vector容器,其底层是怎么实现的?
“vector数据结构和数组非常相似,也称为单端数组。vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展。
vector底层使用动态数组来存储元素对象,同时使用size和capacity记录当前元素的数量和当前动态数组的容量。如果持续的push_back(emplace_back)元素,当size大于capacity时,需要开辟一块更大的动态数组,并把旧动态数组上的元素搬移到当前动态数组,然后销毁旧的动态数组。
push_back做了哪些操作,复杂度如何
“push_back()用于在vector的末尾添加一个元素。如果当前的容量不足以容纳新的元素,那么vector的容量将会翻倍(1.5~2倍),这需要分配新的内存空间并将现有元素复制到新的位置,这是一个O(n)的操作。但是,如果考虑到每个元素平均被复制的次数,push_back()的平摊时间复杂度是O(1)。
有没有什么好的办法提升vector连续插入效率?
“如果知道数据的大概量,我们可以使用reserve方法直接为vector扩容这个量级。这样在后续的数据插入时就不会因为频繁的capacity被用尽而导致的多次的数据搬移,从而提升vector插入效率。
push_back和emplace_back有什么区别?为什么emplace_back效率更高?
“push_back()会创建一个新的对象然后复制到vector中,而emplace_back()则是在vector中直接构造对象,这可以避免不必要的复制或移动操作。
请简单介绍一些set和map
“std::set是一个有序的集合,其中的元素是唯一的,即每个元素只能出现一次。一般用于去重和自动排序。
std::map同样是有序组合,只不过它不止有key,每个key还对用一个value。其中key是唯一,不可重复,但是value却没有限制。key/value也被称为键值对。
他们底层使用什么数据结构存储数据的吗?
“两者都是使用红黑树作为底层的数据结构。红黑树是一种自动平衡的二叉树,它确保插入、删除和查找操作的时间复杂度都是O(log n)。是高效的查找树
map[key]和map.at(key)的区别
“当map中不存在某个key时,map[key]操作会在map中增加一个键值对,键名为key,值是传入的value类型的默认值。而map.at(key)会报错,查找时更安全。
查询而言,是vector快还是map快?
“vector的查询的时间复杂度是O(n),而map是O(logn)。如果在数据集很大的时候,当然是map快一些。但当数据量没那么大的时候(少于1000条记录),vector要比map查询速度快。原因我们在之前的面试文章中讲过,vector内存连续,缓存更友好。map底层是红黑树,内存并不连续。
指针
什么是指针?
“指针的作用:可以通过指针间接访问内存。
内存编号是从0开始记录的,一般用十六进制数字表示。
可以利用指针变量保存地址。
指针所占内存空间?
“在32位操作系统下,不管什么类型的指针都占4个字节的内存。
在64位操作系统下,不管什么类型的指针都占8个字节的内存,但是实际开发环境一般都是32位操作系统下。
什么是空指针和野指针?
“空指针:指针变量指向内存中编号为0的空间(0,NULL,nullptr)。用途:初始化指针变量。空指针指向的内存是不可以访问的。
野指针:指针变量指向非法的内存空间。野就是状态未知的。它可能指向一块未知的区域:0/NULL/nullptr三者之间的区别?
虽然三者都能定义空指针,但三者类型不同。0是int类型,NULL在g++下是一个宏定义,而nullptr是有类型的;建议使用nullptr定义空指针,因为它时有类型的,编译器能够对它进行类型检查。
如何解决空指针、野指针带来的问题?
“
在解引用指针之前,要判断指针是否为空。(解决空指针解引用问题)
对于定义的指针,一定要进行初始化(=nullptr)。(解决野指针问题)
对于释放过内容的指针,立即将指针置为nullptr。(解决垂悬指针、指针二次释放问题)
要注意长生命周期的指针不能指向短生命周期的对象。(解决垂悬指针问题)
C++11之后使用智能指针。
什么是智能指针?有哪些智能指针?
“智能指针是C++11引入的类模板,用于管理资源,行为类似于指针,但不需要手动申请、释放资源,所以称为智能指针。有三种智能指针,分别是shared_ptr、unique_ptr、和weak_ptr 。
这三种智能指针有什么不同和用途?
“shared_ptr使用了引用计数(use count)技术,当复制个shared_ptr对象时,被管理的资源并没有被复制,而是增加了引用计数。当析构一个shared_ptr对象时,也不会直接释放被管理的的资源,而是将引用计数减一。当引用计数为0时,才会真正的释放资源。shared_ptr可以方便的共享资源而不必创建多个资源。
unique_ptr则不同。unique_ptr独占资源,不能拷贝,只能移动。移动过后的unique_ptr实例不再占有资源。当unique_ptr被析构时,会释放所持有的资源。
weak_ptr可以解决shared_ptr所持有的资源循环引用问题。weak_ptr在指向shared_ptr时,并不会增加shared_ptr的引用计数。所以weak_ptr并不知道shared_ptr所持有的资源是否已经被释放。这就要求在使用weak_ptr获取shared_ptr时需要判断shared_ptr是否有效。
static和const
static和const的关键用法?
“satic关键字主要用在以下三个方面:1.用在全局作用域,修饰的变量或者函数为静态的,限制在本文件内使用。2.方法内修饰修饰静态局部变量,在第一次访问的时候初始化。只能在本文件内使用。3.内类修饰成员函数和成员变量,此函数或变量由类持有,而非类的对象持有。
const关键字主要也有三个用途:1.修饰函数参数,则在函数内部不可以修改此参数。2.修饰类的成员方法,表面此方法不会更改类对象的任何数据。3.修饰变量,表明变量不可以被修该。
现在两个指针,一个是
const int*
,另一个是int * const
,两者有什么区别?
“这要要看
const
和*
的位置,const
在前称为常量指针,const
在后称为指针常量。常量指针的指针的指向可变,指针指向的内容不可变。指针常量则相反,指针指向的内容可变,指针的指向不可变。
投稿作者为『自动驾驶之心知识星球』特邀嘉宾,欢迎加入交流!
① 全网独家视频课程
BEV感知、毫米波雷达视觉融合、多传感器标定、多传感器融合、多模态3D目标检测、车道线检测、轨迹预测、在线高精地图、世界模型、点云3D目标检测、目标跟踪、Occupancy、cuda与TensorRT模型部署、大模型与自动驾驶、Nerf、语义分割、自动驾驶仿真、传感器部署、决策规划、轨迹预测等多个方向学习视频(扫码即可学习)

② 国内首个自动驾驶学习社区
近2400人的交流社区,涉及30+自动驾驶技术栈学习路线,想要了解更多自动驾驶感知(2D检测、分割、2D/3D车道线、BEV感知、3D目标检测、Occupancy、多传感器融合、多传感器标定、目标跟踪、光流估计)、自动驾驶定位建图(SLAM、高精地图、局部在线地图)、自动驾驶规划控制/轨迹预测等领域技术方案、AI模型部署落地实战、行业动态、岗位发布,欢迎扫描下方二维码,加入自动驾驶之心知识星球,这是一个真正有干货的地方,与领域大佬交流入门、学习、工作、跳槽上的各类难题,日常分享论文+代码+视频,期待交流!

③【自动驾驶之心】技术交流群
自动驾驶之心是首个自动驾驶开发者社区,聚焦目标检测、语义分割、全景分割、实例分割、关键点检测、车道线、目标跟踪、3D目标检测、BEV感知、多模态感知、Occupancy、多传感器融合、transformer、大模型、点云处理、端到端自动驾驶、SLAM、光流估计、深度估计、轨迹预测、高精地图、NeRF、规划控制、模型部署落地、自动驾驶仿真测试、产品经理、硬件配置、AI求职交流等方向。扫码添加汽车人助理微信邀请入群,备注:学校/公司+方向+昵称(快速入群方式)
④【自动驾驶之心】平台矩阵,欢迎联系我们!