继承
继承是面向对象三大特性之一
有些类与类之间存在特殊的关系
可以发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。
这个时候可以考虑用继承的技术,减少重复代码
继承的基本语法
#include <iostream> using namespace std; class Base { public: void header() { cout << "首页、公开课、登录、注册···(公共头部)" << endl; } void footer() { cout << "帮助中心、交流合作、站内地图···(公共底部)" << endl; } void left() { cout << "Java、Python、C++···(公共分类列表)" << endl; } }; class Java : public Base{ public: void contain() { cout << "Java学科视频" << endl; } }; class Cpp : public Base{ public: void contain() { cout << "cpp学科视频" << endl; } }; void test01() { cout << "Java下载视频页面如下:" << endl; Java ja; ja.header(); ja.footer(); ja.left(); ja.contain(); cout << "------------------------ " << endl; } void test02() { cout << "cpp下载视频页面如下:" << endl; Cpp cpp; cpp.header(); cpp.footer(); cpp.left(); cpp.contain(); cout << "------------------------ " << endl; } int main() { test01(); test02(); }
语法:class 子类 : 继承方式 父类 {}
子类 也称 派生类
父类 也称 基类
继承方式
继承的方式一共有三种:
- 公共继承
- 保护继承
- 私有继承

继承中的对象模型
问题:从父类继承过来的成员,哪些属于子类对象中?
#include <iostream> using namespace std; class Base { public: int m_A; protected: int m_B; private: int m_C;//也被子类继承了 }; class Son : public Base { public: int m_D; }; int main() { //父类中所有非静态的成员属性都会被子类继承下去 //父类中私有的成员属性,是被编译器隐藏了,因此访问不到 ,但是也被继承了 cout << sizeof(Son) << endl; //16 }
继承中构造和析构顺序
子类继承父类后,当创建子类对象,也会调用父类的构造函数
问题:父类和子类的构造和析构顺序是谁先谁后?
#include <iostream> using namespace std; class Base { public: Base() { cout << "Base的构造函数" << endl; } ~Base() { cout << "Base的析构函数" << endl; } }; class Son : public Base { public: Son() { cout << "Son的构造函数" << endl; } ~Son() { cout << "Son的析构函数" << endl; } }; int main() { Son s; // Base的构造函数 // Son的构造函数 // Son的析构函数 // Base的析构函数 }
结论:继承中 先构造父类再构造子类,析构顺序与构造顺序相反
继承同名成员处理方式
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或者父类中同名的数据呢?
- 访问子类同名成员 直接访问即可
- 访问父类同名成员 需要加作用域
using namespace std; class Base { public: Base() { m_A = 100; } void func() { cout << "Base - func()调用" << endl; } void func(int a) { cout << "Base - func(int a)调用" << endl; } int m_A; }; class Son : public Base { public: Son() { m_A = 200; } void func() { cout << "Son - func()调用" << endl; } int m_A; }; int main() { Son s; //同名成员属性 cout << s.m_A << endl; //200 cout << s.Base::m_A << endl; //100 //同名成员函数 s.func(); s.Base::func(); //如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数(重载的也一样) //如果想访问父类中被隐藏的同名成员函数,需要加作用域 s.Base::func(100); }
总结:
- 子类对象可以直接访问到子类中同名成员
- 子类对象加作用域可以访问到父类同名成员
- 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数
继承同名静态成员处理方式
问题:继承中同名的静态成员在子类对象上如何进行访问?
- 访问子类同名成员,直接访问即可
- 访问父类同名成员,需要加作用域
#include <iostream> using namespace std; class Base { public: static void func() { cout << "Base -static func()调用" << endl; } static int m_A; }; int Base::m_A = 100; class Son : public Base { public: static void func() { cout << "Son -static func()调用" << endl; } static int m_A; }; int Son::m_A = 200; int main() { Son s; //通过对象访问 cout << s.m_A << endl; //200 cout << s.Base::m_A << endl; //100 //通过类名访问 cout << Son::m_A << endl; //200 cout << Son::Base::m_A << endl; //100 //成员函数同理 }
总结:同名静态函数处理方式和非静态处理方式一样,只不过有两种访问方式(通过对象 和 通过类名)
多继承语法
C++允许一个类继承多个类
语法: class 子类 :继承方式 父类1,继承方式 父类2··· {}
多继承可能会引发父类中有同名成员出现,需要加作用域区分
菱形继承
菱形继承概念:
- 两个派生类继承同一个基类
- 又有某个类同时继承着两个派生类
- 这种继承被称为菱形继承,或者钻石继承

菱形继承问题:
- 羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性
- 草泥马继承自 动物的数据继承了两份,但这份数据实际只有需要一份
#include <iostream> using namespace std; //动物类 class Animal { public: int m_Age; }; //利用虚继承 解决菱形继承问题 //继承之前加上关键字 virtual 变为虚继承 //Animal类 称为 虚基类 //羊类 class Sheep : virtual public Animal { }; //驼类 class Camel : virtual public Animal { }; //羊驼类 class SheepTuo : public Sheep, public Camel { }; int main() { SheepTuo st; st.m_Age = 18; }


浙公网安备 33010602011771号