一、前言
继承实现代码复用,提取多个类的公共属性 / 行为到父类,子类直接复用并扩展独有功能;多态让同一函数在不同子类表现不同逻辑,是面向对象三大特性(封装、继承、多态)核心之二。
二、继承基础语法
cpp
运行
class 子类名 : 继承方式 父类名
{
子类独有成员;
};
三种继承方式:public公有继承、protected保护继承、private私有继承,日常开发优先使用public。
公有继承示例:学生子类继承人类父类
cpp
运行
#include <iostream>
#include <string>
using namespace std;
// 父类:人类,公共属性姓名、年龄
class Person
{
protected:
string name;
int age;
public:
void setInfo(string n, int a)
{
name = n;
age = a;
}
void showPerson()
{
cout << "姓名:" << name << " 年龄:" << age << endl;
}
};
// 子类:学生,公有继承Person,新增分数属性
class Student : public Person
{
private:
double score;
public:
void setScore(double s)
{
score = s;
}
void showStu()
{
showPerson(); // 复用父类函数
cout << "考试分数:" << score << endl;
}
};
int main()
{
Student s;
s.setInfo("小明", 18); // 调用继承自父类的方法
s.setScore(92);
s.showStu();
return 0;
}
三、三种继承方式权限变化
public公有继承:父类 public→子类 public;父类 protected→子类 protected;父类 private 子类无法访问protected保护继承:父类 public/protected 全部变为子类 protectedprivate私有继承:父类 public/protected 全部变为子类 private,仅当前子类可用,孙子类无法继承
四、继承中构造与析构执行顺序
创建子类对象:先执行父类构造函数 → 再执行子类构造函数
销毁子类对象:先执行子类析构函数 → 再执行父类析构函数
cpp
运行
class Person
{
public:
Person(){cout << "父类Person构造" << endl;}
~Person(){cout << "父类Person析构" << endl;}
};
class Student:public Person
{
public:
Student(){cout << "子类Student构造" << endl;}
~Student(){cout << "子类Student析构" << endl;}
};
int main()
{
Student s;
return 0;
}
输出顺序:父构造→子构造→子析构→父析构
五、子类访问父类私有成员
父类private成员子类无法直接访问,解决方案:
父类成员改为
protected,子类可直接读取修改父类提供 public get/set 接口,子类调用接口操作私有数据
六、虚函数 virtual 实现多态
多态核心:父类指针 / 引用指向子类对象,调用同名函数执行子类重写逻辑。
父类函数添加
virtual变为虚函数子类重写同名、同参数函数(重写 override)
cpp
运行
#include <iostream>
using namespace std;
// 父类动物
class Animal
{
public:
// 虚函数
virtual void speak()
{
cout << "动物发出声音" << endl;
}
};
// 狗子类重写speak
class Dog:public Animal
{
public:
void speak() override
{
cout << "汪汪汪" << endl;
}
};
// 猫子类重写speak
class Cat:public Animal
{
public:
void speak() override
{
cout << "喵喵喵" << endl;
}
};
// 多态统一接口
void talk(Animal &a)
{
a.speak();
}
int main()
{
Dog d;
Cat c;
talk(d); // 输出汪汪汪
talk(c); // 输出喵喵喵
return 0;
}
七、虚析构函数(解决继承内存泄漏)
父类析构不加 virtual 时,父类指针释放子类对象,只会执行父类析构,子类堆内存无法释放。
修复方案:父类析构添加virtual
cpp
运行
class Animal
{
public:
virtual ~Animal()
{
cout << "父类虚析构执行" << endl;
}
};
八、新手避坑
私有继承后,孙子类无法访问父类任何成员,业务开发几乎不用
未写 virtual 虚函数,父类指针调用函数只会执行父类逻辑,无多态效果
继承构造顺序颠倒,子类构造无法直接初始化父类 private 成员
父类析构非 virtual,堆子类对象释放造成内存泄漏
九、综合实战:员工继承体系(普通员工 / 经理多态)
cpp
运行
#include <iostream>
#include <string>
using namespace std;
// 父类员工
class Staff
{
protected:
string name;
int salary;
public:
Staff(string n, int s):name(n),salary(s){}
virtual void showInfo()
{
cout << "员工:" << name << " 基础薪资:" << salary << endl;
}
virtual ~Staff(){}
};
// 普通员工子类
class NormalStaff:public Staff
{
public:
NormalStaff(string n,int s):Staff(n,s){}
void showInfo() override
{
cout << "普通员工:" << name << " 月薪:" << salary << endl;
}
};
// 经理子类
class Manager:public Staff
{
private:
int bonus;
public:
Manager(string n,int s,int b):Staff(n,s),bonus(b){}
void showInfo() override
{
cout << "经理:" << name << " 底薪:" << salary << " 奖金:" << bonus << endl;
}
};
void printStaff(Staff &s)
{
s.showInfo();
}
int main()
{
NormalStaff a("小张",6000);
Manager b("王总",10000,5000);
printStaff(a);
printStaff(b);
return 0;
}
十、下期预告
下一篇:C++ string 标准字符串类全套操作详解