10.重载 隐藏 覆盖 +虚表

#include <iostream>
using namespace std;
//关于多态中  重载:1.在基类中无虚(virtual)关键词;2.返回类型和函数名一样;3.参数列表不一样;同一个类中
//                  重载就是一种多态
//关于多态中  隐藏:1.在基类中无虚(virtual)关键词;2.派生类中有与基类相同名称的函数,不要求返回类型与参数列表。
//                  又称同名隐藏:子类隐藏父类所有的同名函数(这也算是重载只是为了区分第一种)。
//关于多态中  覆盖:1.在基类中有虚(virtual)关键词;2.派生类中有与基类达到三同的函数;3.列外:基类返回基类指针,派生类返回派生类指针
//是指虚表(virtual fun ptr = vfptr)内的覆盖,因在基类中增加虚表,如果基类本身是4字节会变成8字节,增加4个字节的虚表指针

class Q
{   public:
Q():x(0){}
virtual ~Q(){}
void fun(){ cout << "This is Q fun()" << endl; }
void fun(int a){ cout << "This is Q fun(...)" << endl; }
virtual void show(){ cout << "This is Q show()" << endl; }
virtual void print(){ cout << "This is Q print()" << endl; }
private:  int x;
};
class P:public Q
{   public:
P():y(0){}
~P(){}
void fun(){ cout << "This is P fun()" << endl; }
void show(){ cout << "This is Pshow()" << endl; }
virtual void GetP(){ cout << "This is P GetP()" << endl; }
private:  int y;
};

//虚表是由  虚函数的地址+虚函数名组成(先父类再子类),虚表结束是以  0X00000000 为结束符,多个虚表多个结束符。
//单一继承 无覆盖 :先按声明顺序排列父类虚函数,再其后按声明顺序排列子类虚函数
//单一继承 有覆盖 :先按声明顺序排列父类虚函数,再其后按声明顺序排列子类虚函数,
//然后移除子类需覆盖的虚函数所在虚表的信息去覆盖父类同名虚函数(子类替换了父类虚函数所在虚表的地址和函数名)

//多继承   无覆盖:当有N个父类继承时就会有N个虚表。先按父类在子类声明的顺序排列虚表,
//然后在各自虚表内按声明顺序排列父类虚函数,子类虚函数最后排列在第一个父类虚表后面。

//多继承   有覆盖:当有N个父类继承时就会有N个虚表。先按父类在子类声明的顺序排列虚表,
//然后在各自虚表内按声明顺序排列父类虚函数,再第一个父类虚表后按声明顺序排列子类无覆盖虚函数,
//然后移除子类需覆盖的虚函数去覆盖所有父类同名虚函数(子类需覆盖的虚函数替换了所有父类虚函数所在虚表的地址和函数名)
class Base{
public:
virtual void A(){ cout << "This is Base A" << endl; }
virtual void B(){ cout << "This is Base B" << endl; }
virtual void C(){ cout << "This is Base C" << endl; }
private:int x;
};
class Base1{
public:
virtual void A(){ cout << "This is Base1 A" << endl; }
virtual void B(){ cout << "This is Base1 B" << endl; }
virtual void C(){ cout << "This is Base1 C" << endl; }
private:int y;
};
class Base2{
public:
virtual void A(){ cout << "This is Base2 A" << endl; }
virtual void B(){ cout << "This is Base2 B" << endl; }
virtual void C(){ cout << "This is Base2 C" << endl; }
private:int z;
};
class D :public Base{
public:
virtual void A1(){ cout << "This is D A" << endl; }
void B(){ cout << "This is D B" << endl; }//本身就是虚函数
virtual void C1(){ cout << "This is D C" << endl; }
private:int m;
};
class D1 :public Base, public Base1, public Base2{
public:
virtual void A1(){ cout << "This is D1 A" << endl; }
void B(){ cout << "This is D1 B" << endl; }//本身就是虚函数
virtual void C1(){ cout << "This is D C" << endl; }
private:int n;
};
int main(){
Q q;
P p;
Q *pq = &p;
q.fun(10);//fun(10)调用的是基类           重载  过的有参函数
p.fun();//fun()调用的是派生类             隐藏  过的派生类函数
//d.fun(10);//fun(10)不可以调用,因同名   隐藏  所有的基类同名函数
pq->show();//show()调用的是派生类         覆盖  过的派生类函数
D d;//虚表排列:  Base-A -> D-B -> Base-C -> D-A -> D-C (Base-B被D-B覆盖替换掉了)
D1 d1;//3个虚表排列:表1  Base-A ->D1-B -> Base-C -> D-A -> D-C (Base-B被D1-B覆盖替换掉了,
//无覆盖子类虚函数继续接在声明的第一个父类后)
//表2  Base1-A ->D1-B -> Base1-C(Base1-B被D1-B覆盖替换掉了)
//表3  Base2-A ->D1-B -> Base2-C(Base1-B被D1-B覆盖替换掉了)

return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42100881/article/details/80175386