类默认成员函数 & 内存布局

// C++ 编译器默认生成的 6 个函数 (C++11) class MyClass { MyClass(); // 默认构造函数 MyClass(const MyClass&); // 拷贝构造 MyClass(MyClass&&); // 移动构造 (C++11) MyClass& operator=(const MyClass&); // 拷贝赋值 MyClass& operator=(MyClass&&); // 移动赋值 (C++11) ~MyClass(); // 析构函数 }; // 对象内存布局 (有虚函数时) // ┌─────────────────────────────┐ // │ vptr (虚表指针, 8 bytes) │ ← 对象首地址 // ├─────────────────────────────┤ // │ 成员变量 (按声明顺序) │ // └─────────────────────────────┘
💡 static 成员变量属于类,不属于任何实例,所有对象共享同一份。访问方式:ClassName::member 或 obj.member

虚函数 & 多态机制

class Base { public: virtual void speak() { cout << "Base"; } // 虚函数 virtual void pure() = 0; // 纯虚函数 → 抽象类 void normal() {} // 普通函数,不参与多态 }; class Derived : public Base { public: void speak() override { cout << "Derived"; } // 覆盖(不加virtual也生效) void pure() override {} // 必须实现,否则仍为抽象类 }; // 多态调用链: Base* p = new Derived(); p->speak(); // → vptr → vtable[1] → Derived::speak ✓ 运行时多态
⚠️ 为什么不能所有函数都设虚?1) 每个类多一个vptr(8B) 2) 每次调用多一次间接寻址 3) 构造函数不能为虚(对象未构造时vptr不存在)

三种继承 & 析构函数

// 继承方式对比 class B { public: int pub; protected: int pro; private: int pri; }; class D1 : public B {}; // pub→pub, pro→pro, pri→不可访问 class D2 : protected B {}; // pub→pro, pro→pro, pri→不可访问 class D3 : private B {}; // pub→pri, pro→pri, pri→不可访问 // 为什么基类析构必须为虚? class Base { public: virtual ~Base() {} }; // ✓ 正确 // delete base_ptr 时,若析构非虚 → 只调 Base::~Base → 内存泄漏!
💡 子类覆盖父类virtual函数时,加不加virtual关键字都能实现多态(C++标准规定覆盖自动继承虚属性)。子类对象内存中包含父类的所有非静态成员(含private,只是无法直接访问)。

插件化推理框架中的应用

// 插件化推理框架核心设计 class IInferencePlugin { // 抽象接口 public: virtual ~IInferencePlugin() = default; virtual Tensor forward(const Tensor& input) = 0; virtual string name() const = 0; }; // 各后端实现为动态库 (.so/.dll) class CUDAPlugin : public IInferencePlugin { ... }; class ONNXPlugin : public IInferencePlugin { ... }; // 框架通过 vptr/vtable 实现运行时绑定: IInferencePlugin* plugin = loadPlugin("cuda_backend.so"); plugin->forward(data); // 通过虚表分发到具体实现
🔑 虚表机制使框架无需在编译期知道具体实现 → 热插拔、动态加载、ABI兼容性的基础
Generated with Tabbit.