- 继承的概念
继承是面向对象中的一种手段,它可以使代码复用。它允许在一个类的基础上进行扩展,增加功能,这样产生新类称为派生类(子类),最开始的类称为基类(父类)。 - 继承权限
继承的权限有三种:public. protect. private.
详细内容如一下表格:
- 赋值兼容规则
a.派生类是基类经过扩展形成派生类,所以派生类中一定含有基类的内容(还包含有自己的内容)。派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。(可以这么理解)把派生类中父类那部分切来赋值过去。
b.基类对象不能赋值给派生类对象。可以通俗理解,派生类中它自己那部分是基类中没有的,基类对象无法包含这一部分的赋值。故基类对象不能赋值给派生类对象。
c.基类的指针可以通过强制类型转换赋值给派生类的指针。但是必须是基类的指针是指向派生类对象时才是安全的。 - 集成体系中派生类中六个默认成员函数
一般不写的情况下,编译器会默认生成。
派生类中,成员函数的生成方式:
a. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
b. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
c. 派生类的operator=必须要调用基类的operator=完成基类的复制。
d. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
e. 派生类对象初始化先调用基类构造再调派生类构造。
f. 派生类对象析构清理先调用派生类析构再调基类的析构。 - 友元与继承
友元函数不被继承。通俗理解,属于基类的内容才能被继承,而友元函数不是类的成员函数,故,无法继承。 - 静态成员与继承
静态成员不被继承。基类定义了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";
}
二义性问题的解决:虚拟继承。如上面代码中的继承关系,在Student和Teacher的继承
Person时使用虚拟继承。
10. 设置一个不能被继承的类 (前面博客重点讲有,略过!)