Skip to content

面向对象概念速查(重载/重写/隐藏/struct/class 等)

一、重载(overload) vs 重写(override) vs 隐藏(hide)

概念判定条件发生在例子
重载 overload同作用域、同名、参数不同同一类内 / 全局f(int)f(double)f(int,int)
重写 override派生类定义与基类虚函数同名同参继承层级、基类须 virtualvoid speak() override
隐藏 hide派生类定义与基类同名(不管参数),遮蔽基类版继承层级派生 void f(int) 遮蔽基类所有 f

要点

  • 重载只看参数签名;返回类型不参与重载决议。
  • override 要求签名完全一致(含 const、参数类型),否则就是 hide(此时加 override 会编译报错,帮你发现 bug)。
  • 名字查找规则:派生类先在自己的作用域找,找不到才向上找基类 —— 所以派生类里定义同名会遮蔽基类所有同名(即便参数不同)。要用基类重载需 using Base::f;

二、struct vs class

维度structclass
默认访问控制publicprivate
继承默认public 继承private 继承
其它成员函数/继承/模板等能力与 class 完全一样同左
  • 习惯约定:struct 表示数据聚合(POD/简单数据),class 表示带封装行为的对象。语法能力等价,仅默认访问/继承控制不同。
  • C 中 struct 只有数据;C++ 是 C 的超集扩展。

三、union vs struct

structunion
内存各成员顺序共存(大小≈成员和+对齐)各成员共享起始地址(大小≈最大成员)
同时有效所有成员同时可访问同一时刻只有一个成员有效
用途组合对象节省内存的互斥存储 / 传输协议
  • union 大小 = 最大成员大小;union 成员在运行期切换时需自行管理当前「活跃成员」。
  • C++ 里 union 成员可以是类对象(需注意构造/析构,常用 variant 替代)。

四、三大特性速记

  • 封装:数据 + 方法绑在一起,隐藏细节(访问控制 public/protected/private)。
  • 继承:复用与扩展,形成 is-a 关系。
  • 多态:同一接口、不同实现(见 polymorphism.md)。

C++ 相比 Java:多继承、运算符重载、模板/泛型(编译期多态)、无 GC(RAII)、值语义与引用语义共存(对象可值传递)。

五、访问控制速查

访问级别本类派生类外部
public
protected
private
  • protected 成员对「派生类对象访问基类部分的 protected 成员」有一定限制(要继承而来的才可访问,不能通过任意 Base 对象访问其 protected)——较细节,面试可答「规则存在,一般只会问本类/派生/外部三级」。实际 C++ 规则:通过派生类类型的对象只能访问继承来的 protected;通过基类类型访问派生类对象里的 protected 不行。

六、构造函数初始化列表 vs 赋值

cpp
class A {
    const int c_;        // 必须初始化列表
    int& r_;             // 引用必须初始化列表
    Base b_;             // 想调参数构造
public:
    A(int c, int& x, int v) : c_(c), r_(x), b_(v) {}  // ✅ 在进入函数体前完成
};
  • const、引用、无默认构造的成员只能用初始化列表。
  • 初始化列表按声明的顺序初始化(不是列表顺序),常作面试陷阱:若成员声明顺序与列表顺序不一致,先初始化成员可能仍用未赋值变量。
  • 在函数体内赋值是「先默认构造再赋值」,多一次构造,且 const/引用成员不可这样。

七、对象切片(object slicing)

按值传递/返回派生类到基类会切割成基类部分:丢失派生数据、丢失多态(按值没有 vptr 作用)。传参用基类引用/指针避免切片。

C++ 面试八股 · VitePress 版