1 C/C++概念
1.1 简述C++的特点
- 支持面向对象程序设计,包括封装、继承和多态三大特征
- 更加安全,增加了const变量、引用&、智能指针、try_catch等
- 引入了模板的概念,可复用性高
- 跨平台
1.2 各种变量之间的区别
主要看生命周期和作用域
1.3 new和malloc的区别
new是一个操作符,malloc是一个函数
malloc内存分配成功返回的是void*,需要强制类型转换,而new无需进行
malloc分配内存失败会返回NULL,new则返回bac_alloc的异常
1.4 有了malloc/free 为什么还要new/delete ?
malloc/free是函数,无法在创建对象时自动执行构造函数,也无法再消亡时自动执行析构函数,因此需要new和delete
new创建的是一个对象,malloc分配的是一块内存区域
1.5 指针函数和函数指针的区别?
函数指针:指向函数的指针变量,可以通过指针调用函数
1 |
|
指针函数:返回值为指针的函数,比如,int * func()
1.6 野指针
指向“垃圾”内存的指针,由于未初始化指针、数据已删除或超出作用域都会产生
2 面向对象
2.1 什么是面向对象
一种软件开发方法,也是一种编程范式,将相关数据和对这些数据的操作组织称一个整体,成为“对象”。
2.2 面向对象的三大特征
封装、继承、多态
- 封装:将属性和方法打包在一起,形成一个“类”,并对其加以权限控制
- 继承:让某个类型的对象获得另外一个类型对象的属性和方法的机制。
- 多态:通过基类指针可以调用任何派生类的函数。多态分为编译时的多态(重载),运行时的多态(虚函数)。
三大特性使得编程更加灵活,提高代码的可读性、可复用性、可维护性
2.3 RAII
Resource Acquisition Is Initialization 资源获取初始化,是C++的一种资源管理策略,将资源的生命周期和对象的生命周期绑定在一起,资源的获取和释放是通过构造和析构函数
2.4 组合和继承
继承:一个类 继承 另一个类 的属性和操作
组合:一个类 包含 另一个类的对象做成员
1 | class Engine{}; |
继承的缺点:子类和父类的耦合度高,多层继承导致复杂的关系,代码可维护性变差
2.5 为什么基类的析构最好为虚析构?
防止内存泄漏,如果想通过基类释放派生类的资源,没有虚函数就只会调用基类的析构函数,派生类的资源就没办法释放
2.6 重写和重载
重写(override)指的是派生类重新实现基类的虚函数
重载(Overload)是指在同一个作用域内允许多个函数具有相同的名称,但是参数列表不同(包括参数数量、类型或顺序)
2.7 delete 和 default
对于默认构造函数,只有在没有声明其他任何构造函数的情况下,才会自动的生成,否则就需要开发者去手工定义无参的构造函数,下面这段代码就会报错:
1 | class classB { |
但是默认的构造函数效率比较高,我们如果想用默认的无参构造就可以用default关键字
1 | class classB { |
前面智能指针样例里说到,我们可能会希望定义的类,不允许通过拷贝或者赋值的方式初始化,只允许默认的构造函数,那么就可以使用delete关键字
1 | class classB { |
3 其他
3.1 extern “C”
告诉编译器,应该按照C语言的方式进行处理
在C++的函数中,编译器会对函数名包含额外的信息(参数类型等),C语言就不会,因此C++函数和C语言函数链接的时候就不兼容。
extern “C”只会影响声明函数,不会影响内部函数的C++代码实现
3.2 模板
模板是泛型编程,手写的一个模板函数可以在编译阶段解释出很多个不同类型的函数
3.3 map和unordered_map有什么区别
map基于红黑树,能确保元素的有序
unordered_map基于哈希表,不保证元素的有序性
3.4 mutable
mutable关键字可以应用于类定义的成员变量,表示这个成员变量可以在常量函数中被修改
1 | calss myclss{ |
上面的操作都是可以的