二、面向对象编程(OOP)(共18项)
1.C/C++中面向对象的相关知识
2.什么是纯虚函数抽象类
3.什么是多态?多态有什么作用?
4.重载和覆盖有什么区别?
5.C++中类默认有哪些成员函数?
6.C++中哪一种成员变量可以在一个类的实例之间共享?
7.继承层次中,为什么基类析构函数是虚函数?
8.面向对象技术的基本概念是什么,三个基本特性是什么?
9.为什么构造函数不能为虚函数?
10.虚函数是什么?为什么不能把所有函数设为虚函数?
11.什么是多态?多态有什么作用?
12.什么是公有继承、受保护继承、私有继承?
13.什么是虚指针?
14.C++如何阻止一个类被实例化?
15.类使用static成员的优点,如何访问?
16.一个父类写了一个virtual函数,如果子类覆盖它的函数不加virtual,也能实现多态?在子类的空间里,有没有父类的这个函数,或者父类的私有变量?
17.多态实现方式是什么?
18.C++对象模型、虚表、虚指针在插件化推理框架中有什么意义?
结论先行
这18个问题串起了 C++ 面向对象编程的“三板斧”:封装、继承、多态。
- 封装决定类/对象如何隐藏状态、暴露接口;
- 继承实现代码复用与“是一个(is-a)”关系;
- 多态让基类指针能调用子类实现,核心实现靠 虚函数 + 虚表 + 虚指针。
在插件化推理框架中,这些机制正好用来定义稳定的抽象算子/后端接口(抽象类+虚函数),运行时通过虚表动态分派到不同插件实现,实现“接口不变、实现可插拔”。
逐条简明解释
1. C/C++ 中面向对象的相关知识
C 语言本身不是面向对象语言,但可以用结构体+函数指针模拟封装与多态。
C++ 原生支持:类、对象、封装、继承、多态、虚函数、抽象类、模板等。核心是把数据 + 操作数据的函数绑定在一起。
2. 纯虚函数与抽象类
virtual void foo() = 0; // 纯虚函数
含有纯虚函数的类叫抽象类,不能直接实例化,只能被继承,强制子类实现接口。类似于 Java 的 interface 或 Python 的抽象基类。
3. 什么是多态?有什么作用?
多态就是“同一接口,不同表现”。
- 编译时多态:函数重载、模板。
- 运行时多态:虚函数 + 基类指针/引用。
作用:降低耦合、增强扩展性,写通用代码时不必关心具体子类类型。
4. 重载(Overload)与覆盖(Override)的区别
| 维度 | 重载 | 覆盖 |
|---|---|---|
| 发生范围 | 同一作用域内 | 基类与派生类之间 |
| 函数签名 | 必须不同(参数列表不同) | 必须相同(除协变返回) |
| 关键字 | 不需要 virtual | 基类函数必须 virtual |
| 绑定时机 | 编译期 | 运行期 |
5. C++ 类默认有哪些成员函数?
编译器会在需要时自动生成:
- 默认构造函数
- 拷贝构造函数
- 拷贝赋值运算符
- 移动构造函数(C++11)
- 移动赋值运算符(C++11)
- 析构函数
C++11 起,可用
= default显式默认、= delete显式删除。
6. 哪种成员变量可在类实例之间共享?
static 成员变量。
所有对象共用同一份存储,不属于某个对象,需在类外定义并初始化。
class A { static int count; };
int A::count = 0; // 类外初始化
7. 为什么基类析构函数应为虚函数?
如果基类指针指向派生类对象,用 delete base_ptr 释放时:
- 析构函数不是虚函数 → 只调用基类析构,派生类资源泄漏。
- 析构函数是虚函数 → 通过虚表正确调用派生类析构,再调基类析构。
原则:有虚函数的类、或会被多态删除的基类,析构函数必须为 virtual。
8. 面向对象的基本概念与三大特性
- 基本概念:类、对象、封装、继承、多态、消息传递。
- 三大特性:封装、继承、多态。
9. 为什么构造函数不能为虚函数?
- 构造时对象类型还未完整,虚表尚未构建完成,无法动态分派。
- 虚函数调用依赖虚指针,而虚指针正是在构造函数中初始化的。
- 从语义上,派生类构造需要先构造基类部分,基类构造期间并不知道自己是派生类。
10. 虚函数是什么?为什么不能把所有函数设为虚函数?
虚函数是在基类声明为 virtual、允许派生类重写并通过基类指针动态调用的成员函数。
不能全部设为虚函数的原因:
- 性能开销:每次调用需查虚表,有间接跳转和缓存未命中。
- 对象体积:每个对象额外增加虚指针。
- 设计语义:很多函数不需要多态,强制虚函数破坏内联和静态优化。
11. 同 3,略。
一句话:接口统一,实现可变,扩展方便。
12. 公有、受保护、私有继承
| 继承方式 | 基类 public 成员 | 基类 protected 成员 | 基类 private 成员 | 语义 |
|---|---|---|---|---|
public 继承 | public | protected | 不可见 | is-a 关系 |
protected 继承 | protected | protected | 不可见 | 实现细节复用 |
private 继承 | private | private | 不可见 | has-a / 实现继承 |
默认
class私有继承,struct公有继承。
13. 什么是虚指针?
每个含虚函数的类对象,编译器会隐式插入一个 虚指针(vptr),指向该类的 虚函数表(vtable)。通过它实现运行时多态。
14. C++ 如何阻止一个类被实例化?
- 构造函数设为
private或protected(单例、工厂常用)。 - 声明纯虚函数,使其成为抽象类。
- C++11 起可用
= delete删除构造函数。
class NonInstantiable {
public:
NonInstantiable() = delete;
};
15. static 成员的优点与访问方式
优点:
- 所有对象共享,节省内存。
- 可作为全局状态/计数器,作用域限定在类内,避免命名污染。
- 类级行为,不依赖对象实例。
访问:
ClassName::staticVar; // 推荐
obj.staticVar; // 也可通过对象访问,但语义上是类共享
16. 子类覆盖父类 virtual 函数时不加 virtual,能否多态?子类空间里有没有父类函数/私有变量?
- 能实现多态。在 C++ 中,只要基类函数是
virtual,派生类中同名同签函数会自动成为虚函数(建议显式加override)。 - 子类对象空间里包含父类子对象:父类的非静态成员变量都会存在,包括私有变量,只是派生类无法直接访问。
- 父类的虚函数在 vtable 中会被子类版本覆盖/替换,但父类自己的实现仍作为独立函数存在,可通过作用域调用:
Base::foo()。
17. 多态的实现方式
- 静态多态:函数重载、运算符重载、模板(编译期确定)。
- 动态多态:虚函数 + 虚表 + 虚指针(运行期确定)。
18. C++ 对象模型、虚表、虚指针在插件化推理框架中的意义
插件化推理框架常见设计:
- 定义抽象基类
Op、Backend、InferenceEngine,包含纯虚接口。 - 各后端/算子以动态库(
.so/.dll)形式实现并继承这些基类。 - 主程序通过
dlopen/dlsym加载插件,返回基类指针/智能指针。 - 虚表 + 虚指针保证运行期正确分派到插件具体实现,主程序无需重新编译即可接入新后端。
意义:
- 解耦:核心框架与具体推理实现分离。
- 可扩展:新增模型格式或硬件后端只需新增插件。
- 统一接口:同一套推理 API 适配 CPU/GPU/NPU 等多种设备。
这些问题之间的联系
它们共同描绘了 C++ OOP 的完整图景:
类与对象
封装
继承
多态
虚函数
虚表 vtable
虚指针 vptr
抽象类/接口
插件化框架

- 封装通过访问控制和构造函数管理对象状态。
- 继承复用并扩展基类。
- 多态让继承体系“活”起来,而多态依赖 vptr + vtable。
- 抽象类 + 虚析构为插件/框架提供安全、稳定的扩展边界。
- static 成员则处理“类级别”的共享状态,与实例级状态互补。
掌握这些,你就能设计出像插件化推理框架这样“高内聚、低耦合、可扩展”的 C++ 系统。
&spm=1001.2101.3001.5002&articleId=163844361&d=1&t=3&u=601f732c9bae47c18b3877da27009698)
2430

被折叠的 条评论
为什么被折叠?



