C++—继承
一、继承的概念及定义
1.1继承的概念
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Person
{
public:
void Print()
{
cout << "name->" << _name << endl;
cout << "age->" << _age<< endl;
}
protected:
string _name = "peter";//姓名
int _age = 9;//年龄
};
class Student : public Person//这里的Student类继承了Person这个类
{
protected:
int _stuid;
};
class Teacher : public Person//这里的Teacher类继承了Person这个类
{
protected:
int _J;
};
int main()
{
Student s;
Teacher t;
s.Print();
t.Print();
return 0;
}
我们继承下来的类,既继承了他的成员变量,还继承了他的成员函数。
上面代码运行结果可以看出s、t调用的Print都是Person类的成员函数;
1.2 继承定义
1.2.1定义格式
下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。
1.2.2继承关系和访问限定符
访问限定符类似在类和对象中protected和private没有区别,但是在继承中protected和private就有所区别了。
1.2.3继承基类成员访问方式的变化
类成员/继承方式 | public继承 | protected继承 | private继承 |
---|---|---|---|
基类的public成员 | 派生类的public成员 | 派生类的protected成 员 | 派生类的private成 员 |
基类的protected成 员 | 派生类的protected成 员 | 派生类的protected成 员 | 派生类的private成 员 |
基类的private成员 | 在派生类中不可见 | 在派生类中不可见 | 在派生类中不可见 |
总结:
二、基类和派生类对象赋值转换
三、继承中的作用域
四、派生类的默认成员函数
派生类的重点的四个默认成员函数,我们不写,编译器会默认生成的会干些什么呢?
什么情况下必须自己去写?
那如果我们要自己写怎么办,如何自己去写?
五、继承与友元
友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。
六、继承与静态成员
**基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。**无论派生出多少个子类,都只有一个static成员实例 。
子类去访问,访问的都是同一个。
七、复杂的菱形继承及菱形虚拟继承
菱形继承代码如下:存在数据冗余和二义性问题,虽然指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决。
class Person
{
public :
string _name ; // 姓名
};
class Student : public Person
{
protected :
int _num ; //学号
};
class Teacher : public Person
{
protected :
int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
string _majorCourse ; // 主修课程
};
void Test ()
{
// 这样会有二义性无法明确知道访问的是哪一个
Assistant a ;
a._name = "peter";
// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
a.Student::_name = "xxx";
a.Teacher::_name = "yyy"; }
那如何解决呢?
虚拟继承解决数据冗余和二义性的原理
下图是非虚继承的情况下:
下图是虚继承的情况下:
下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?
这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。