C++继承
继承的好处:减少重复代码
语法:
class 子类(派生类):继承方式 父类(基类)
class son :public base{
};
A为子类,或称为派生类,其中的成员包括:从基类继承的成员、自己增加的成员。
继承方式有三种:
- 公共继承public,访问权限不变
- 保护继承protected,除了私有内容,其余内容都变为保护权限
- 私有继承private,除了私有内容,其余内容都变为私有权限
注意:
虽然父类中的私有成员访问不到,被编译器给隐藏了,但父类中的所有非静态成员属性都会被子类继承下去
验证私有成员仍被继承在子类中的方法:
- 从“开始”菜单中找到Visual Studio中的“开发人员命令提示符(Developer Command Prompt for VS 2019)”
- 打开对应项目文件存放的目录
- 输入
cl /d1 reportSingleClassLayoutXXX "YYY.cpp"
,其中XXX代表要查看的类名,YYY.cpp代表程序对应的.cpp文件
继承同名成员处理方式
当子类与父类出现同名的成员时:
-
访问子类中同名成员,直接访问即可;
son.m_A
-
访问父类同名成员,需要加作用域。
son.base::m_A
原因:如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中的所有同名成员函数。如果要访问到父类中被隐藏的同名函数,就需要加作用域。
多继承语法
C++允许一个类继承多个类
语法:
class 子类 : 继承方式 父类1 , 继承方式 父类2……
class son: public base1, public base2{
};
多继承可能会引发父类中有同名成员出现,需要加作用域区分
在实际开发中不建议用多继承
菱形继承
概念:
两个派生类(C2、C3)继承同一个基类(C1)
又有某个类(C4)同时继承两个派生类(C2、C3)
例如:
//动物类
class Animal{
public:
int m_Age; //动物的最大年龄
};
//羊类
class Sheep :public Animal {};
//驼类
class Camel :public Animal {};
//羊驼类
class Alpaca :public Sheep, public Camel {};
程序中,羊类和驼类都有自己的最大年龄,羊驼哪知道应该调用哪一个,所以在使用时必须加上作用域:
int main()
{
Alpaca yangtuo; //定义一个羊驼类成员
//当菱形继承时,两个父类拥有相同数据,需要加作用域区分
yangtuo.Sheep::m_Age = 18; //继承羊的最大年龄
yangtuo.Camel::m_Age = 28; //继承驼的最大年龄
cout << "yangtuo.Sheep::m_Age= " << yangtuo.Sheep::m_Age << endl;
cout << "yangtuo.Camel::m_Age= " << yangtuo.Camel::m_Age << endl;
return 0;
}
输出结果为:
从结果来看,羊驼同时继承了羊类的最大年龄和驼类的最大年龄,但羊驼只能有一个最大年龄吧,这就是使用菱形继承时存在的隐藏问题。
菱形继承可能会导致资源的浪费,利用虚继承可以解决菱形继承的问题
在继承之前,加上关键字virtual变为虚继承,它的基类(Animal)就变为虚基类
虚继承方法:
//羊类
class Sheep :virtual public Animal {};//驼类
class Camel :virtual public Animal {};
修改后的输出结果:
从结果可看出,现在羊驼的最大年龄取决于最后一个输入的最大年龄值。