cpp八股
智能指针
C++ 中有三种主要的智能指针:
-
std::shared_ptr:共享指针。它允许多个指针共享同一个对象,并且会自动管理对象的生命周期。当最后一个std::shared_ptr指向对象销毁时,对象也会被销毁。 -
std::unique_ptr:独占指针。它允许一个指针独占拥有一个对象,并负责管理对象的生命周期。当std::unique_ptr被销毁时,它会自动删除所指向的对象。 -
std::weak_ptr:弱引用指针。它是std::shared_ptr的一种扩展,用于解决循环引用的问题。std::weak_ptr允许你观察std::shared_ptr指向的对象,但不会增加对象的引用计数,从而避免循环引用。
这些智能指针有助于管理动态分配的内存,提高代码的安全性和可维护性,避免内存泄漏和悬挂指针等问题。
右值引用
C++ 中的右值引用是一种引用类型,用于处理临时对象(右值)。右值引用的语法是使用双 && 符号声明,例如:
int&& rvalue_ref = 42; // 右值引用绑定到临时整数值
移动语义
右值引用允许将资源(如动态分配的内存或文件句柄)从一个对象“移动”到另一个对象,而不是进行深层复制。这可以提高性能,避免不必要的数据复制。
std::vector<int> GetVector() {
std::vector<int> temp = {1, 2, 3};
return temp; // 返回一个临时的右值
}
std::vector<int> myVector = GetVector(); // 使用移动语义,避免复制
完美转发 Perfect Forwarding
std::forward实现通用的函数模板,能够正确的传递参数,无论传递的是左值还是右值
template <typename T>
void Forward(T&& value) {
some_functionsforward<T>(value); // 完美转发参数
}
右值引用通常与 C++11 引入的移动语义和 C++14 引入的完美转发一起使用,以提高性能和代码的灵活性。它们是现代 C++ 中的重要特性,用于更有效地管理资源和编写通用代码。
面向对象-封装继承多态
封装 代码重用 隐藏细节,模块化
继承 代码重用 扩展已有模块
多态 接口重用
封装
| class | struct | |
|---|---|---|
| 继承权限 | private | public |
| 访问权限 | private | public |
| 一般struct倾向于c时代的struct,只包含成员变量,没有逻辑,用来将多个变量打包成一个类型 |
继承
1、子类拥有父类非private的属性和方法
2、子类可以拥有自己属性和方法(扩展)
3、子类可以用自己的方式实现父类的方法
构造器
super()
| 子类 | 外界 | |
|---|---|---|
| private | x | x |
| protected | √ | x |
向上转型
- 继承是对封装的破坏——暴露内部实现、强耦合
- 是否需要从子类向父类进行向上转型?
- √:继承是必要的(比如多态)
- x:则应当好好考虑
多态
静态多态 重载
运行多态 虚函数表vtb,虚函数表指针vtpr
dynamic_cast
堆内存、栈内存
| 栈 | 堆 | |
|---|---|---|
| 空间管理 | 高效 | 有碎片 |
| 访问权限 | 只能局部变量 | 全局变量 |
| 空间大小 | 操作系统限制 | 没有特定限制 |
| 内存分配 | 连续(水位线) | 随机分配 |
| 分配释放 | 自动管理 | free\delete |
| 限制 | 空间小 | 内存碎片 |
| 多线程风险 | ||
| static静态区,全局变量和静态变量被分配到同一块内存中。程序结束后由系统释放。 |
模板类的作用,和泛型的区别
map,unordered_map是否线程安全
gcc编译过程
unit test UT
前序、中序、后序遍历
如果获得了前序、后序遍历的结果,能否完全还原二叉树的结构?