佳期投资 C++开发 一面
1. 在 C++ 中,智能指针有哪些类型,重点说一下 unique_ptr 和 shared_ptr 的区别
答案:常见智能指针主要有 unique_ptr、shared_ptr、weak_ptr,以及比较早期的 auto_ptr,不过 auto_ptr 已经被废弃了。unique_ptr 表示独占所有权,同一时刻只能有一个智能指针拥有对象,不能拷贝,只能移动,所以它的开销最小,也最符合“资源独占”的语义。shared_ptr 表示共享所有权,多个智能指针可以共同管理同一个对象,底层通常依赖控制块维护引用计数。最后一个 shared_ptr 析构时,对象才会真正释放。两者最大的区别在于所有权模型和成本。unique_ptr 更轻量,适合对象生命周期明确、不会共享的场景;shared_ptr 更灵活,但有额外控制块、引用计数维护成本,而且容易出现循环引用。weak_ptr 本身不拥有对象,主要是配合 shared_ptr 解决循环引用和观察对象是否还存活的问题。
代码:
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> p1 = make_unique<int>(10);
// unique_ptr<int> p2 = p1; // 错误,不能拷贝
unique_ptr<int> p2 = move(p1);
shared_ptr<int> s1 = make_shared<int>(20);
shared_ptr<int> s2 = s1;
cout << *p2 << endl;
cout << *s1 << " " << s1.use_count() << endl;
return 0;
}
2. 对于 C++17 和 C++20 的新特性,你了解哪些
C++17 我比较常用的有结构化绑定、if constexpr、折叠表达式、std::optional、std::variant、std::string_view、并行算法,还有返回值优化规则加强。像 string_view 很适合只读字符串视图传递,可以减少不必要拷贝;optional 很适合表达“可能有值也可能没有值”的语义,比返回特殊值更清晰。C++20 比较典型的是 concepts、ranges、coroutine、std::span、三路比较、模块、jthread 和更完整的原子等待通知机制。如果从工程角度看,C++20 最大的几个提升点,一个是 concepts 让模板约束更清晰,一个是 coroutine 对异步编程表达能力更强,一个是 ranges 能把算法和容器操作写得更自然。
代码:
#include <iostream>
#include <optional>
#include <tuple>
using namespace std;
optional<int> findValue(bool ok) {
if (ok) return 42;
return nullopt;
}
int main() {
auto [a, b] = pair<int, int>{1, 2}; // C++17 结构化绑定
cout << a << " " << b << endl;
auto res = findValue(true);
if (res) cout << *res << endl;
return 0;
}
3. C++ 中类的内存布局通常是怎样的,如果包含虚函数会发生什么变化
一个普通类对象的内存通常由成员变量按声明顺序排布,中间可能因为对齐要求插入 padding。如果类里有普通成员函数,这些函数代码本身不在对象内存里,对象里只存数据成员。如果类包含虚函数,主流编译器实现里对象内部通常会多出一个隐藏的虚表指针,也就是 vptr,它指向该类型对应的虚函数表。这样对象大小通常会变大,至少要多出一个指针大小。如果存在继承,尤其是多继承、虚继承,内存布局会更复杂,编译器可能还会插入额外指针、偏移信息来支持运行时多态和基类定位。所以类对象内存布局不能只看源码里写了哪些成员,还要考虑对齐、虚函数、继承模型这些因素。
代码:
#include <iostream>
using namespace std;
class A {
int x;
char y;
};
class B {
public:
virtual void foo() {}
int x;
char y;
};
int main() {
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
return 0;
}
4. 除了类内存布局,你了解对象模型里 this 指针、静态成员和虚函数表分别放在哪吗
this 指针不是对象里的一个显式成员,它本质上是成员函数调用时编译器隐式传入的一个参数,用来指向当前对象。静态成员变量不属于某个具体对象,它通常存放在静态存储区,所有对象共享同一份。普通成员函数和虚函数的代码段本身都在程序代码区,不在对象实例内部。虚函数表通常也是编译器生成的一张静态表,放在只读数据区或者类似区域,对象内部只保存一个 vptr 指向它。所以对象实例真正占内存的,通常是非静态数据成员以及编译器为对象模型附加的隐藏指针,而不是函数代码和静态成员。
5. C++ 中可以控制内存对齐吗,特别是在网络传输场景里怎么保证结构紧凑
可以。C++ 里可以通过 alig
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.