大家好,我是网域小星球。
本篇是 C++ 面试核心最后一篇,覆盖继承、多态、this 指针、深浅拷贝、三大特性,全部是 C++ 开发岗必问手撕考点。学完这 4 篇,足以应对 C++ 初试、笔试、基础面试提问,代码可直接在 VS2022 运行。
目录
一、本章学习目标
二、this 指针(面试高频基础)
1. 核心概念
2. 代码示例
面试常问
三、继承(C++ 三大特性之二)
1. 继承作用
2. 继承语法
3. 公有继承代码示例
4. 继承访问权限规则(面试必背)
5. 构造与析构继承顺序
四、浅拷贝 & 深拷贝(面试超级高频)
1. 浅拷贝
2. 深拷贝
完整对比代码
面试标准答案
五、多态 & 虚函数(C++ 最难、面试必问)
1. 多态概念
2. 实现多态三个条件
3. 虚函数 + 多态完整示例
4. 虚析构函数(面试大坑)
六、C++ 三大特性 面试简答背诵版
七、C++ 开发岗 高频简答汇总(直接背)
八、本篇总结
一、本章学习目标
- 掌握 C++ 三大特性:封装、继承、多态完整概念
- 吃透继承语法、访问控制、菱形继承问题
- 理解this 指针面试常考原理
- 分清浅拷贝 & 深拷贝(内存泄漏高频题)
- 掌握多态、虚函数核心原理与代码
二、this 指针(面试高频基础)
1. 核心概念
this是成员函数隐含指针,指向当前调用该函数的对象。
- 每个非静态成员函数,都自带一个
this形参 - 作用:区分成员变量和局部同名变量、返回当前对象、操作自身成员
2. 代码示例
#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; }面试常问
- this 指针存放在哪里?答:栈区,作为成员函数隐式形参传入。
- this 可以为空吗?答:可以,空 this 调用函数不崩溃,只要不解引用成员。
三、继承(C++ 三大特性之二)
1. 继承作用
复用代码、减少冗余、实现层级设计,子类复用父类成员与方法。
2. 继承语法
class 子类 : 继承方式 父类 { // 子类独有成员 };三种继承方式:
public公有继承(最常用)protected保护继承private私有继承
3. 公有继承代码示例
// 父类 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. 继承访问权限规则(面试必背)
- 父类
public→ 子类public - 父类
protected→ 子类protected - 父类
private→ 子类不可访问
5. 构造与析构继承顺序
构造:先父类,后子类析构:先子类,后父类
四、浅拷贝 & 深拷贝(面试超级高频)
1. 浅拷贝
编译器默认拷贝构造,只拷贝地址,不拷贝堆内存内容。
- 多个对象共用同一块堆空间
- 析构时重复释放内存 → 程序崩溃
2. 深拷贝
手动写拷贝构造,重新开辟堆内存,每个对象独立资源。
完整对比代码
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. 实现多态三个条件
- 必须有继承
- 父类函数加virtual虚函数
- 父类指针 / 引用 指向子类
3. 虚函数 + 多态完整示例
#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; }运行结果:
猫咪喵喵叫 狗狗汪汪叫4. 虚析构函数(面试大坑)
父类析构必须加virtual,否则子类析构不执行,内存泄漏。
virtual ~Animal(){}六、C++ 三大特性 面试简答背诵版
- 封装将属性私有化,对外提供接口,隐藏实现细节,提高安全性。
- 继承子类复用父类代码,降低冗余,实现代码复用。
- 多态父类引用指向子类,统一接口、不同实现,提高扩展性。
七、C++ 开发岗 高频简答汇总(直接背)
- 引用和指针区别?
- 重载和重写区别?
- 浅拷贝深拷贝区别?
- 多态实现原理?
- 虚函数作用?
- 构造、析构能否为虚函数?
- this 指针是什么?
1. 引用 和 指针 的区别
- 引用是变量别名,无独立内存;指针是独立变量,存储地址,占用空间。
- 引用必须初始化,且不可变更指向;指针可以不初始化、可随意改指向。
- 无空引用;存在空指针、野指针。
- 引用更安全简洁;指针更灵活,可用于跨函数修改、动态内存。
- 引用底层依旧是指针,但语法层面屏蔽了风险。
2. 重载 和 重写(覆盖)区别
重载(overload)
- 同一作用域、函数名相同、参数列表不同
- 编译期绑定,与返回值无关
- 属于静态多态
重写(override)
- 发生在继承关系中
- 子类重写父类virtual 虚函数
- 函数名、参数、返回值完全一致
- 运行时绑定,实现动态多态
3. 浅拷贝 与 深拷贝 区别
- 浅拷贝:只拷贝指针地址,堆内存资源共享,析构重复释放导致崩溃。
- 深拷贝:手动开辟新堆空间,拷贝内容,每个对象资源独立。
- 类中有
new动态成员时,必须自己实现深拷贝。
4. 多态的实现原理
- 必须满足三大条件:继承 + 虚函数 + 父类指针 / 引用指向子类
- 含有虚函数的类,会生成虚函数表 (vtable)
- 对象内存在虚表指针 (vptr)
- 程序运行时通过 vptr 查找虚表,调用子类重写的函数
- 实现运行时多态
5. 虚函数作用
- 实现多态,父类统一接口,子类不同实现。
- 继承场景中,通过父类指针正确调用子类方法。
- 虚析构保证子类析构函数正常执行,避免内存泄漏。
6. this 指针是什么
- this 指针是非静态成员函数的隐含形参。
- 指向当前正在调用成员函数的对象。
- 用于区分局部变量与成员变量、返回当前对象。
- 存放于栈上,由编译器自动传递。
7. 构造函数、析构函数 能否是虚函数?
① 构造函数不能是虚函数
原因:
- 虚函数依赖虚表指针 vptr。
- vptr 在构造函数执行完毕后才会初始化。
- 构造阶段对象还未完整创建,没有虚表,无法实现虚函数调用。
② 析构函数可以是虚函数,并且建议写为虚析构
场景:当父类指针指向子类对象时:
- 如果析构非虚 → 只调用父类析构,子类资源不释放,内存泄漏
- 如果析构为虚 → 触发多态,先析构子类,再析构父类
八、本篇总结
- this 指针是对象内置隐式指针,解决成员同名问题;
- 继承实现代码复用,必须注意构造析构顺序;
- 浅拷贝共享堆内存会崩溃,深拷贝手动开空间;
- 虚函数 + 继承 + 父类指针 = 多态;
- 虚析构防止继承场景内存泄漏;