继承
继承是类设计层次的复用
class Person;
{
public:
void Print()
{
cout<< "name: " << _name <<endl;
cout<< "name: " << _name <<endl;
}
protected:
string _name = "XX";
int _age ="X";
}
// 派生类 继承方式 基类
class student : public Person
{
protected:
int _stuID;
}
class Teacher : public Person
{
protected:
int _workID;
}
//此时Person为父类 即基类;student称为子类,即派生类
继承关系和访问限定符
继承基类成员访问方式的变化
类成员/继承方式 | public继承 | protrcted继承 | privated继承 |
---|---|---|---|
基类的public成员 | 派生类的public成员 | 派生类的protected成员 | 派生类的privated成员 |
基类的protected成员 | 派生类的protected成员 | 派生类的protected成员 | 派生类的privated成员 |
基类的privated成员 | 不可见 | 不可见 | 不可见 |
- 不可见 即指的是基类的私有成员还是被继承到派生类对象中,但是语法上限制派生类对象无论在类外,类里都不能访问.
- 使用class关键字默认的继承方式是private,使用struct默认继承方式是public
- 一般使用public继承,增强可维护性
基类和派生类对象赋值转换
派生类对象可以赋值给基类的对象/基类的指针/基类的应用.称为切片/切割,即把派生类中父类的部分切割赋值过去.
class Person;
{
public:
void Print()
{
cout<< "name: " << _name <<endl;
cout<< "name: " << _name <<endl;
}
protected:
string _name = "XX";
string _sex = "X"
int _age ="X";
}
// 派生类 继承方式 基类
class student : public Person
{
protected:
int _stuID;
}
void Test()
{
Student sobj;
//1.子类对象可以赋值给父类对象/指针/引用
Person pobj = sobj;
Person* pp = &sobj;
Person& rp = sboj;
//2.基类对象不能赋值给派生类对象
sobj = pobj;
//3.基类的指针可以通过强制类型转换赋值给派生类的指针
pp = &sobj;
Student* ps1 = (Stendent*)pp;//此时可以转换
ps1->_No = 20;
pp = &pobj;
Student* ps2 = (Student*)pp;//此时可以转换,但是可能会存在越界访问
}
继承中的作用域
- 继承体系中基类和派生类都有独立的作用域
- 子类和父类有同名成员,子类成员将屏蔽父类同名成员的直接访问即 隐藏 . 也叫重定义(在子类成员函数中,可以使用 基类::基类成员 显示访问)
- 如果是成员函数的隐藏,只需要函数名相同就构成隐藏
- 在继承体系中尽量不定义同名成员
派生类的默认成员函数
- 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化
- 派生类的operator=必须要**调用基类的operator=**完成基类的复制
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序
- 派生类对象初始化先调用基类构造再调派生类构造
- 派生类对象析构清理先调用派生类析构再调基类的析构
继承与友元
友元函数不能继承, 即基类友元不能访问子类私有和保护成员
继承与静态成员
基类定义了static静态成员,则整个继承体系中只有一个这样的成员.
菱形继承
单继承: 一个子类只有一个直接父类时称为整个继承关系为单继承
class person
class student : public person
class postgraduate : public student
多继承 : 一个子类有两个或以上直接父类时称为多继承
class student
class teacher
class assistant : public student,public teacher
菱形继承 : 菱形继承是多继承的一种特殊情况
class person
class student : public person
class teacher : public person
class assistant : public student,public teacher
菱形继承存在数据冗余和二义性,在assistant 的对象中会有person成员会有两份. 此时需要虚拟继承来解决.
class person
class student : virtual public person
class teacher : virtual public person
class assistant : public student,public teacher
assistant对象将person放到组成对象的最下面,person同属student和teacher,通过student和teacher的两个虚基表指针指向虚基表, 虚基表中存的偏移量,通过偏移量找到person.