佳期投资 C++开发 一面

1. 在 C++ 中,智能指针有哪些类型,重点说一下 unique_ptr 和 shared_ptr 的区别

答案:常见智能指针主要有 unique_ptrshared_ptrweak_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::optionalstd::variantstd::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++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务