== 继承是根据已有的类创建新类的过程
== c++中,假设类B继承了类A,那么称类A为父类或者基类,类B称为子类或者派生类。
例如
class A
{};
class B : public A
{};
== 可以看出上面的继承是public继承(公有继承),还有其他两种继承,分别是private继承、protected继承。
它们之间的区别是:1.公有继承:基类的公有成员和保护成员,也是派生类的公有成员和保护成员。(成员包括成员变量和成员函数)。
2.私有继承:基类的公有成员和保护成员将成为派生类的私有成员。
3.基类的公有成员和保护成员将成为派生类的保护成员。
== 注意:基类的私有成员都是不能被派生类访问的,若想访问,只能通过基类的公有函数或保护函数去访问。
== 我们知道一个类在创建一个对象的时候会调用这个类的构造函数,那么问题来了,我有一个类B继承了类A,那么谁的构造函数先执行呢?
答案当然是A类的构造函数先执行,因为A类是父类,没有父何来的子呢。
== 那如果一个类继承了多个父类,那此时的构造函数执行顺序是如何的呢?
此时的顺序取决于继承时的顺序;
即假设
class A
{};
class B
{};
class C : public A,public B
{};
== 那么此时的构造函数执行顺序应该是ABC
子类的构造函数永远是最后执行的。
无法继承的成员:
1.基类的构造函数、析构函数、拷贝构造函数
2.基类的重载运算符
3.基类的友元函数(你父亲的朋友不一定是你的朋友)
当基类与派生类有同名函数时,调用时会调用派生类的函数,基类的函数则会被隐藏,想要使用基类的函数,需要在前面加上基类名与域操作符。
多继承与多重继承
首先,先明确一点:多继承 ≠ 多重继承
1.多继承
语法: class 子类 :继承方式 父类1 , 继承方式 父类2...
class Base1 {
public:
Base1()
{
m_A = 100;
}
public:
int m_A;
};
class Base2 {
public:
Base2()
{
m_A = 200; //开始是m_B 不会出问题,但是改为mA就会出现不明确
}
public:
int m_A;
};
//语法:class 子类:继承方式 父类1 ,继承方式 父类2
class Son : public Base2, public Base1
{
public:
Son()
{
m_C = 300;
m_D = 400;
}
public:
int m_C;
int m_D;
};
多继承可能会引发父类中有同名成员的出现,需要加作用域区分。
c++实际开发中不建议用多继承
2.多重继承
和多继承一次继承几个类不同,多重继承着重体现在“重”
例如
人类->士兵类->步兵类
一重接一重的继承
== 3.菱形继承
有一个基类A,类B和类C继承类A,类D多继承与类B和类C,那么就构成了一个菱形,那么就会引发一个问题,在创建类D的对象时,类A的构造函数会被调用两次,那么就会造成数据冗余。
解决方案:虚继承virtual;
例如
羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性。 草泥马继承自动物的数据继承了两份,其实我们应该清楚,这份数据我们只需要一份就可以。
class Animal
{
public:
int m_Age;
};
//继承前加virtual关键字后,变为虚继承
//此时公共的父类Animal称为虚基类
class Sheep : virtual public Animal {};
class Tuo : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};
void test01()
{
SheepTuo st;
st.Sheep::m_Age = 100;
st.Tuo::m_Age = 200;
cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
cout << "st.m_Age = " << st.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}
菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义
利用虚继承可以解决菱形继承问题