Skip to content

C++ 冷门/边角语法辨析(知识点粒度太小、归到 misc)

取自常见面经里零散的“一声带过”条目(含 huihut C++ 篇的边角):它们各自答不了多少分钟,但偶尔被抽中,值得过一遍眼熟。

一、位域 bit-field

cpp
struct Flags { unsigned a:1, b:3, c:4; };   // 紧凑按位存放
  • 位域成员宽度由实现决定布局(大小端、是否跨字节/对齐由编译器排)——不可移植地依赖其字节布局/地址
  • &f.a 不合法(位域无独立地址),位数超类型宽度不行。
  • 用途:协议头、节省内存的标志位。性能/可移植场景慎用,常被显示 struct+掩码替代。

二、union 与大小端 / 字节序(HPC/网络相关)

union 成员共享首地址 → 常见“判断大小端”面试小技巧:

cpp
union { int i; unsigned char c[4]; } u;
u.i = 1;
// 若 u.c[0]==1 → 小端(little-endian):低字节在前
  • 主机字节序 vs 网络字节序(network: big-endian):跨平台协议一律用网络字节序,发送前 htonl/htons,收到 ntohl/ntohs
  • 内存对齐里 union 大小=最大成员并对齐(见 memory/alignment)。

三、friend 友元 / using 声明

  • friend:授予全局函数/别的类访问本类 private/protected。别滥用(破封装);常见于 operator<<、内部 builder、测试。
  • using A::f; 在派生类把基类某重载“拉回可见”(消除隐藏,见 oop/concepts);using Base::Base; 继承构造函数(全部);using 别名 = 类型

四、explicit / export / import

  • explicit:阻止单参构造函数/转换运算符被隐式转换调用。
    cpp
    struct A { explicit A(int){} };
    void f(A);  f(3);            // ❌ 需显式 A(3)
    C++20 起 explicit(bool) 可按条件。
  • export:历史模板导出,C++11 已废(罕见古董)。
  • import(C++20 module 概念,见 modern-cpp/views-format)。

五、聚合类 initializer_list / 赋值

  • std::initializer_list<T>{} 让容器支持 {1,2,3} 初始化(见 vector 部分)。
  • 聚合初始化 T t{...}; 整体一次构造,避免默认构造+赋值。

六、C 实现 C++ 类的“概念”题(思路题,答框架)

用 struct + 函数指针模拟“方法/虚表”:

cpp
struct Vtbl { void (*speak)(void*); };
struct Dog { struct Vtbl* vt; void* impl; };
void dog_speak(void*){}

能答“把成员函数变成函数指针成员、用回调做多态雏形”即表达你懂对象模型本质。纯加分废话少说。

七、冷门易错点连发(快速自查,全对说明扎实)

  1. 构造函数内 virtual 不触发派生覆写(vptr 尚未指向最终类)——见 vtable。
  2. 类里成员初始化列表按声明顺序(非书写顺序)。
  3. auto x(){ return 1; } OK;C++14 泛型 lambda [](auto){} 隐式模板。
  4. 句柄/嵌套:连续 >>(C++11 前要 > >)——历史抱怨,C++11 修复,别再说错。
  5. 右括号 }; :类和函数不一样,别忘。
  6. static 成员在类内只能是声明,需要在类外/或者 constexpr/inline 定义(C++17 inline 变量可类内跨 TU)——否则 undefined ref。
  7. constexpr 成员函数默认 const(C++14 前);C++14 后非 const 也可 constexpr。
  8. 迭代删除与 erase 返回值/失效见 stl/iterator。

八、命名/风格不影响对错但面试观感

  • 抛:小写字母/专有名;避免单字母;RAII 明确 ownership。
  • 聊得到 RAII/Copy-Move/Move-once 等“语言生克”细节加分,见 smart-pointers/oop。

C++ 面试八股 · VitePress 版