继承同名成员处理
问题:如果子类与父类存在同名成员,那么如何通过子类对象访问子类或父类的同名成员
解决方式:
1.访问子类同名成员,直接访问即可
2.访问父类同名成员,需要添加作用域
原因是:当子类有与父类同名的成员时,编译器会自动屏蔽父类的所有同名成员
同名成员又分为同名成员属性和同名成员函数,两者其实本质一样
成员属性:
son son1;
son1.m_a = 100;
son1.base::m_a = 1000;
cout << "son1.m_a = " << son1.m_a << endl;
cout << "son1.base::m_a = " << son1.base::m_a << endl;
成员函数:
son son1;
son1.print();
son1.base::print();
如果,父类的同名函数有重载现象,那么在使用的时候,依然要加上作用域。
【父类中所有同名函数被子类的同名函数屏蔽了】
多继承语法
C++允许一个类继承多个父类(基类)
使用语法如下:
class son : public base1, public base2 {};
多继承可能会引发父类有同名成员出现,需要加作用域加以区分
当父类出现同名成员,需要加作用域予以区分。一般不建议使用多继承
菱形继承
菱形继承概念:
1.两个派生类(子类)继承于一个基类(父类)
2.又有派生类(子类)同时继承这两个派生类(父类)
这种继承方式就是菱形继承,又称钻石继承
菱形继承经典案例---羊驼
菱形继承的问题:
1.当孙子类使用数据时,其两个父类的数据都来源于爷爷类,使用数时会有二义性问题
解决方法:菱形继承时,当父类拥有相同数据时,需要加作用域加以区分
void test()
{
alpaca al1;
al1.sheep::m_age = 18;
al1.camel::m_age = 20;
cout << "al1.sheep::m_age = " << al1.sheep::m_age << endl;
cout << "al1.camel::m_age = " << al1.camel::m_age << endl;
}
2.孙子类继承了爷爷类两份数据,造成资源浪费,其实需要一份就可以了
解决方法:利用虚继承的方式,解决资源浪费的问题
在父类继承的时候,加上关键字 virtual ,这样,继承方式就变为虚继承,爷爷类就变成了虚基类
class animal
{
public:
int m_age;
};
class sheep :virtual public animal{};
class camel :virtual public animal{};
class alpaca :public sheep, public camel{};
如此一来,继承的数据就只有一份了,而且不用加数据域,十分方便。
原理:父类继承的并不是数据,而是VBPTR(虚基指针),可以通过偏移量找到真正的数据