当前位置: 首页 > news >正文

C++面试7——继承与多态

在C++面试中,继承与多态是考察面向对象理解深度的核心考点。以下是深入浅出的解析,包含关键概念、技术细节和面试常见陷阱:


继承(Inheritance)

核心概念
  1. "is-a"关系:派生类(Derived)是基类(Base)的特殊化(如Car继承Vehicle
  2. 代码复用:派生类继承基类的成员(数据+方法)
  3. 访问控制
    • public继承:基类public→派生public,protected→protected
    • protected继承:基类public/protected→派生protected
    • private继承:基类所有成员→派生private(极少用)
面试高频坑点
  1. 切片问题(Slicing)

    class Base { /*...*/ };
    class Derived : public Base { /*...*/ };Derived d;
    Base b = d;  // 对象切片!丢失Derived特有成员
    

    解决方案:使用指针/引用 Base& b = d;

  2. 构造函数调用顺序

    class Derived : public Base {
    public:Derived() : Base() {}  // 必须显式调用基类有参构造
    };
    
    • 构造顺序:基类→成员对象→自身
    • 析构顺序:自身→成员对象→基类
  3. 名字隐藏(Name Hiding)

    class Base {
    public:void func(int) {}
    };
    class Derived : public Base {
    public:void func() {}  // 隐藏Base::func(int)!
    };Derived d;
    d.func(1);  // 错误!被隐藏
    d.Base::func(1);  // 正确但丑陋
    

    解决:使用using Base::func;引入基类函数


多态(Polymorphism)

核心概念
  1. 动态绑定:运行时根据对象实际类型调用函数
  2. 实现机制:虚函数表(vtable)+ 虚指针(vptr)
    • 每个含虚函数的类有自己的vtable
    • 对象创建时vptr指向对应vtable
  3. 关键语法
    class Shape {
    public:virtual double area() const = 0;  // 纯虚函数→抽象类virtual ~Shape() {}               // 虚析构!必须!
    };
    class Circle : public Shape {
    public:double area() const override { /*...*/ }  // override确保正确重写
    };
    
面试致命陷阱
  1. 忘记虚析构函数

    Base* p = new Derived();
    delete p;  // 若~Base()非虚→仅调用~Base()!内存泄漏!
    

    规则:基类有虚函数时,析构函数必须为虚

  2. 虚函数默认参数静态绑定

    class Base {
    public:virtual void print(int x = 1) { cout << x; }
    };
    class Derived : public Base {
    public:void print(int x = 2) override { cout << x; }
    };Base* p = new Derived();
    p->print();  // 输出1!默认参数静态绑定(Base版)
    

    解决:避免在虚函数中使用默认参数

  3. 构造函数/析构函数中调用虚函数

    class Base {
    public:Base() { callVirt(); }  // 危险!virtual void callVirt() { cout << "Base"; }
    };
    class Derived : public Base {
    public:void callVirt() override { cout << "Derived"; }
    };Derived d;  // 输出"Base"!构造期间对象类型是Base
    

    原理:构造/析构期间虚函数机制未完全生效


继承 vs 组合:面试灵魂拷问

场景继承组合(包含对象成员)
关系“is-a” (Car is a Vehicle)“has-a” (Car has an Engine)
耦合度高耦合低耦合
复用白盒复用(了解基类实现)黑盒复用(仅使用接口)
典型误用为复用公共代码而继承(应组合)需要多态时未用继承

黄金法则

  • 需要多态 → 用继承
  • 只需复用代码 → 用组合
  • 避免多继承(菱形继承问题)

面试实战技巧

  1. 必考问题

    • “虚函数实现原理?” → 答vptr+vtable
    • “为什么需要虚析构?” → 举例内存泄漏场景
    • “override关键字作用?” → 防止签名错误隐藏函数
  2. 代码题陷阱

    class A { 
    public: virtual void f() { cout << "A"; }
    };
    class B : public A {
    public:void f() { cout << "B"; }
    };A* pa = new B();
    pa->f();       // 问输出?→ B(多态正确)
    delete pa;     // 问是否安全?→ 不安全!若~A()非虚则UB
    
  3. 高级话题

    • 动态转换:dynamic_cast<Derived*>(basePtr)(需RTTI)
    • final关键字:禁止派生/重写
    class NoDerived final { /*...*/ };  // 禁止继承
    class Base {
    public:virtual void lock() final;  // 禁止重写
    };
    

总结:面试回答模板

"C++多态通过虚函数机制实现,核心是运行时动态绑定。使用时需注意:

  1. 基类声明虚析构函数防止资源泄漏
  2. 使用override确保正确重写虚函数
  3. 避免在构造/析构中调用虚函数
  4. 优先用组合代替继承除非需要多态

继承应严格满足Liskov替换原则:派生类必须能替代基类工作"

掌握这些要点,面试官会认为你真正理解C++面向对象的精髓!

http://www.dtcms.com/a/294936.html

相关文章:

  • Xorg占用显卡内存问题和编译opencv GPU版本
  • InnoDB的redo log和 undo log
  • 智能小e-集成配置
  • Nestjs框架: 基于Prisma的多租户功能集成和优化
  • 使用抓取 API 可靠高效地提取亚马逊 (Amazon)数据
  • CCD工业相机系统设计——基于FPGA设计
  • SQL执行顺序
  • LLM 隐藏层特征增强技术
  • 同步型降压转换器的“同步”是什么意思?
  • Vite 7.0 引入的几个重要新 API 详解
  • 三极管与场效应管的对比
  • Python脚本服务器迁移至K8S集群部署
  • k8s中的configmap存储
  • JavaWeb-Servlet
  • 内外网互传文件 安全、可控、便捷的跨网数据交换
  • 服务器版本信息泄露-iis返回包暴露服务器版本信息
  • Node.js 倒计时图片服务部署与 Nginx 反向代理实战总结
  • RCE随笔-奇技淫巧(2)
  • Android热修复实现方案深度分析
  • AI面试如何提升物流行业招聘效率?实战案例解析
  • ESP32-S3学习笔记<5>:SPI的应用
  • JDK 介绍与使用指南
  • CMake进阶:检查头文件存在性(check_include_file 和 check_include_fileCXX)
  • uniapp拦截返回事件
  • 应该切换到 NVMe 吗?
  • 学习 Pandas 库:Series 与 DataFrame 核心操作指南
  • c语言:预处理详解
  • CRMEB 单商户PRO多商户通用去版权教程
  • 二叉树解析
  • 51c大模型~合集158