C++ 从 0 入门(四)|继承、多态、this 指针、深浅拷贝(C++ 面试终极收官)

大家好,我是网域小星球。

本篇是 C++ 面试核心最后一篇,覆盖继承、多态、this 指针、深浅拷贝、三大特性,全部是 C++ 开发岗必问手撕考点。学完这 4 篇,足以应对 C++ 初试、笔试、基础面试提问,代码可直接在 VS2022 运行。

目录

一、本章学习目标

[二、this 指针(面试高频基础)](#二、this 指针(面试高频基础))

[1. 核心概念](#1. 核心概念)

[2. 代码示例](#2. 代码示例)

面试常问

[三、继承(C++ 三大特性之二)](#三、继承(C++ 三大特性之二))

[1. 继承作用](#1. 继承作用)

[2. 继承语法](#2. 继承语法)

[3. 公有继承代码示例](#3. 公有继承代码示例)

[4. 继承访问权限规则(面试必背)](#4. 继承访问权限规则(面试必背))

[5. 构造与析构继承顺序](#5. 构造与析构继承顺序)

[四、浅拷贝 & 深拷贝(面试超级高频)](#四、浅拷贝 & 深拷贝(面试超级高频))

[1. 浅拷贝](#1. 浅拷贝)

[2. 深拷贝](#2. 深拷贝)

完整对比代码

面试标准答案

[五、多态 & 虚函数(C++ 最难、面试必问)](#五、多态 & 虚函数(C++ 最难、面试必问))

[1. 多态概念](#1. 多态概念)

[2. 实现多态三个条件](#2. 实现多态三个条件)

[3. 虚函数 + 多态完整示例](#3. 虚函数 + 多态完整示例)

[4. 虚析构函数(面试大坑)](#4. 虚析构函数(面试大坑))

[六、C++ 三大特性 面试简答背诵版](#六、C++ 三大特性 面试简答背诵版)

[七、C++ 开发岗 高频简答汇总(直接背)](#七、C++ 开发岗 高频简答汇总(直接背))

八、本篇总结

一、本章学习目标

  1. 掌握 C++ 三大特性:封装、继承、多态完整概念
  2. 吃透继承语法、访问控制、菱形继承问题
  3. 理解 this 指针 面试常考原理
  4. 分清 浅拷贝 & 深拷贝(内存泄漏高频题)
  5. 掌握 多态、虚函数 核心原理与代码

二、this 指针(面试高频基础)

1. 核心概念

this成员函数隐含指针,指向当前调用该函数的对象。

  • 每个非静态成员函数,都自带一个 this 形参
  • 作用:区分成员变量和局部同名变量、返回当前对象、操作自身成员

2. 代码示例

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
    string name;
    int age;

    Person(string name, int age)
    {
        // this->name 代表成员变量
        this->name = name;
        this->age = age;
    }

    void show()
    {
        cout << this->name << " " << this->age << endl;
    }
};

int main()
{
    Person p("李四", 18);
    p.show();
    return 0;
}

面试常问

  1. this 指针存放在哪里?答:栈区,作为成员函数隐式形参传入。
  2. this 可以为空吗?答:可以,空 this 调用函数不崩溃,只要不解引用成员。

三、继承(C++ 三大特性之二)

1. 继承作用

复用代码、减少冗余、实现层级设计,子类复用父类成员与方法

2. 继承语法

cpp 复制代码
class 子类 : 继承方式 父类
{
    // 子类独有成员
};

三种继承方式:

  • public 公有继承(最常用)
  • protected 保护继承
  • private 私有继承

3. 公有继承代码示例

cpp 复制代码
// 父类
class Animal
{
public:
    void eat()
    {
        cout << "动物需要进食" << endl;
    }
};

// 子类 公有继承
class Dog : public Animal
{
public:
    void bark()
    {
        cout << "狗狗汪汪叫" << endl;
    }
};

int main()
{
    Dog d;
    d.eat();  // 继承父类
    d.bark(); // 自己独有
    return 0;
}

4. 继承访问权限规则(面试必背)

  1. 父类 public → 子类 public
  2. 父类 protected → 子类 protected
  3. 父类 private → 子类不可访问

5. 构造与析构继承顺序

构造:先父类,后子类 析构:先子类,后父类


四、浅拷贝 & 深拷贝(面试超级高频)

1. 浅拷贝

编译器默认拷贝构造,只拷贝地址,不拷贝堆内存内容

  • 多个对象共用同一块堆空间
  • 析构时重复释放内存 → 程序崩溃

2. 深拷贝

手动写拷贝构造,重新开辟堆内存,每个对象独立资源。

完整对比代码

cpp 复制代码
class Student
{
public:
    char* msg;

    // 构造:堆内存申请
    Student()
    {
        msg = new char[20];
    }

    // 浅拷贝(默认)
    //Student(const Student& s) = default;

    // 深拷贝(手写)
    Student(const Student& s)
    {
        msg = new char[20];  // 重新开空间
        strcpy(msg, s.msg);
    }

    ~Student()
    {
        delete[] msg;
    }
};

面试标准答案

  • 浅拷贝:只拷贝指针地址,资源共享,容易重复释放内存。
  • 深拷贝:开辟新内存,资源独立,避免内存泄漏与崩溃。

五、多态 & 虚函数(C++ 最难、面试必问)

1. 多态概念

一个接口,多种实现父类指针 / 引用 指向子类对象,调用虚函数,执行子类重写逻辑。

2. 实现多态三个条件

  1. 必须有继承
  2. 父类函数加 virtual 虚函数
  3. 父类指针 / 引用 指向子类

3. 虚函数 + 多态完整示例

cpp 复制代码
#include <iostream>
using namespace std;

class Animal
{
public:
    // 虚函数
    virtual void speak()
    {
        cout << "动物发声" << endl;
    }
};

class Cat : public Animal
{
public:
    // 重写
    void speak() override
    {
        cout << "猫咪喵喵叫" << endl;
    }
};

class Dog : public Animal
{
public:
    void speak() override
    {
        cout << "狗狗汪汪叫" << endl;
    }
};

// 多态接口
void test(Animal& a)
{
    a.speak();
}

int main()
{
    Cat c;
    Dog d;
    test(c);
    test(d);
    return 0;
}

运行结果:

cpp 复制代码
猫咪喵喵叫
狗狗汪汪叫

4. 虚析构函数(面试大坑)

父类析构必须加 virtual,否则子类析构不执行,内存泄漏

cpp 复制代码
virtual ~Animal(){}

六、C++ 三大特性 面试简答背诵版

  1. 封装将属性私有化,对外提供接口,隐藏实现细节,提高安全性。
  2. 继承子类复用父类代码,降低冗余,实现代码复用。
  3. 多态父类引用指向子类,统一接口、不同实现,提高扩展性。

七、C++ 开发岗 高频简答汇总(直接背)

  1. 引用和指针区别?
  2. 重载和重写区别?
  3. 浅拷贝深拷贝区别?
  4. 多态实现原理?
  5. 虚函数作用?
  6. 构造、析构能否为虚函数?
  7. this 指针是什么?

1. 引用 和 指针 的区别

  1. 引用是变量别名,无独立内存;指针是独立变量,存储地址,占用空间。
  2. 引用必须初始化,且不可变更指向;指针可以不初始化、可随意改指向。
  3. 无空引用;存在空指针、野指针。
  4. 引用更安全简洁;指针更灵活,可用于跨函数修改、动态内存。
  5. 引用底层依旧是指针,但语法层面屏蔽了风险。

2. 重载 和 重写(覆盖)区别

重载(overload)

  • 同一作用域、函数名相同、参数列表不同
  • 编译期绑定,与返回值无关
  • 属于静态多态

重写(override)

  • 发生在继承关系
  • 子类重写父类 virtual 虚函数
  • 函数名、参数、返回值完全一致
  • 运行时绑定,实现动态多态

3. 浅拷贝 与 深拷贝 区别

  1. 浅拷贝:只拷贝指针地址,堆内存资源共享,析构重复释放导致崩溃。
  2. 深拷贝:手动开辟新堆空间,拷贝内容,每个对象资源独立。
  3. 类中有 new 动态成员时,必须自己实现深拷贝

4. 多态的实现原理

  1. 必须满足三大条件:继承 + 虚函数 + 父类指针 / 引用指向子类
  2. 含有虚函数的类,会生成虚函数表 (vtable)
  3. 对象内存在虚表指针 (vptr)
  4. 程序运行时通过 vptr 查找虚表,调用子类重写的函数
  5. 实现运行时多态

5. 虚函数作用

  1. 实现多态,父类统一接口,子类不同实现。
  2. 继承场景中,通过父类指针正确调用子类方法。
  3. 虚析构保证子类析构函数正常执行,避免内存泄漏。

6. this 指针是什么

  1. this 指针是非静态成员函数的隐含形参
  2. 指向当前正在调用成员函数的对象。
  3. 用于区分局部变量与成员变量、返回当前对象。
  4. 存放于栈上,由编译器自动传递。

7. 构造函数、析构函数 能否是虚函数?

① 构造函数 不能 是虚函数

原因:

  1. 虚函数依赖 虚表指针 vptr
  2. vptr 在构造函数执行完毕后才会初始化。
  3. 构造阶段对象还未完整创建,没有虚表,无法实现虚函数调用。

② 析构函数 可以 是虚函数,并且建议写为虚析构

场景:当父类指针指向子类对象时:

  • 如果析构非虚 → 只调用父类析构,子类资源不释放,内存泄漏
  • 如果析构为虚 → 触发多态,先析构子类,再析构父类

八、本篇总结

  1. this 指针是对象内置隐式指针,解决成员同名问题;
  2. 继承实现代码复用,必须注意构造析构顺序;
  3. 浅拷贝共享堆内存会崩溃,深拷贝手动开空间;
  4. 虚函数 + 继承 + 父类指针 = 多态;
  5. 虚析构防止继承场景内存泄漏;
相关推荐
CoderYanger2 小时前
14届蓝桥杯省赛Java A 组Q1~Q3
java·开发语言·线性代数·算法·职场和发展·蓝桥杯
钮钴禄·爱因斯晨2 小时前
他到底喜欢我吗?赛博塔罗Java+前端实现,一键解答!
java·开发语言·前端·javascript·css·html
布说在见2 小时前
企业级 Java 登录注册系统构建指南(附核心代码与配置)
java·开发语言
草莓熊Lotso2 小时前
一文读懂 Java 主流编译器:特性、场景与选择指南
java·开发语言·经验分享
想唱rap2 小时前
C++智能指针
linux·jvm·数据结构·c++·mysql·ubuntu·bash
疯狂成瘾者2 小时前
Java 常见 Map 对比总结:HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap
java·开发语言·spring
XMYX-02 小时前
16 - Go 协程(goroutine):从基础到实战
开发语言·golang
txxzjmzlh2 小时前
Thread 类的基本用法
java·开发语言
wq_3 小时前
Mysql-MVCC
mysql·面试