1.继承
面向对象程序设计的核心思想是数据抽象,继承和动态绑定(封装,继承,多态)。通过数据抽象可以将类的接口和实现分离;通过继承可以定义相似的类型;通过动态绑定可以在一定程度上忽略相似类型的区别,而以统一的方式使用它们的对象。
继承有基类和派生类(父类和子类)。
继承关系
继承关系有三种:
注意和访问控制符区分:
public:公有,任何位置都可以访问
private:私有成员,只有类自己的成员函数才能访问
protected: 保护成员,只有类自己和子类的成员函数才能访问
类型兼容原则:
类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,**公有派生类实际就具备了基类的所有功能,**凡是基类能解决的问题,公有派生类都可以解决。
子类对象可以赋值给父类对象,父类对象不能赋值给子类对象
父类指针/引用可以指向子类对象,子类指针/引用不可以指向父类对象(可强转)
tips:
重载:范围相同,函数名相同,参数不同,virtual可有可无
覆盖:范围不同,函数名相同,参数相同,基类必须有virtual关键字
隐藏:如果派生类函数与基类同名,但参数不同,此时无论有无virtual基类都会被隐藏;如果派生类函数与基类同名,参数也相同,但基类没有virtual,此时基类函数被隐藏。
构造函数调用顺序:基类——派生类成员变量——派生类
析构函数调用顺序:派生类——派生类成员变量——基类
友元函数不能被继承,因为不属于类。
继承类型
https://blog.csdn.net/c_base_jin/article/details/86036185
1.单继承
一个派生类只有一个直接基类
class stu : public person
所占内存大小为父类+子类特有成员变量
2.多继承
一个派生类有两个或以上直接基类
class stu : public person, public gender
所占内存大小为所有父类成员变量+子类特有成员变量
多个基类中有成员同名时,可以使用作用域运算符::进行限定
3.菱形继承
!
多重继承中特殊的形式。也存在二义性,还会造成内存浪费。
比如类C中会存在两份基类N。引用基类N中的数据还需要通过域运算符区分。
所以引入了虚基类,使得在间接继承共同基类时只保留一份基类成员。虚基类并不是在声明基类时声明的,而是在声明派生类时指定继承方式声明的。在最后的派生类中不仅要对直接基类进行初始化,还要负责对虚基类初始化。
C++编译系统只执行最后的派生类对基类的构造函数调用,而忽略其他派生类对虚基类的构造函数调用。从而避免对基类数据成员重复初始化。因此,虚基类只会构造一次。
//公共基类
class N
{
public:
N(int data1, int data2, int data3) :
m_data1(data1),
m_data2(data2),
m_data3(data3)
{
std::cout << "call common constructor" << std::endl;
}
virtual ~N(){
}
void display()
{
std::cout << m_data1 << std::endl