多态&多态对象模型

xiaoxiao2021-02-28  76

1:什么是多态? 多态就是多种形态。 满足构成多态的条件:必须有虚函数的重写(函数名,参数,返回值均相同,协变除外) 父类的指针或引用调用虚函数 多态跟类型无关而和对象有关,如果不构成多态则与类型有关 父类必须为虚函数,子类可以是也可以不是,构造函数不能为虚函数。

class A { public: virtual void func()//父类必须为虚函数 { cout << "A::func()" << endl; } protected: int _a; }; class B:public A { public: virtual void func() { cout << "B::func()" << endl; } protected: int _b; }; //void f(A* a) void f(A& a)//父类的指针或引用调用虚函数 { a.func(); } int main() { A a; B b; f(a); f(b); A* p1 = &a; p1->func(); p1 = &b; p1->func(); system("pause"); return 0; }

如果A中没有virtual,则以上都调用父类

2:多态的对象模型–单继承&多继承? 虚函数表是通过一块连续内存来存储虚函数的地址。解决了继承,虚函数(重写)的问题,指明了实际调用虚函数的问题。

#include<iostream> using namespace std; typedef void(*V_FUNC)(); class A { public: virtual void func1() { cout << "A::func1()" << endl; } virtual void func2() { cout << "A::func2()" << endl; } protected: int a; }; class B:public A { public: virtual void func1() { cout << "B::func1()" << endl; } virtual void func3() { cout << "B::func3()" << endl; } virtual void func4() { cout << "B::func4()" << endl; } protected: int b; }; void PrintVtable(int vtable)//打印虚表 { int *vfArray = (int*)vtable; printf("vtable:0x%p\n", vfArray); for (size_t i = 0; vfArray[i] != 0; ++i)//虚表以0结束 { printf("vfunc[%d]:0x%p->", i, vfArray[i]); V_FUNC f = (V_FUNC)vfArray[i]; f(); } cout << endl; } int main() { A a; B b; PrintVtable(*((int*)&a)); PrintVtable(*((int*)&b)); system("pause"); return 0; }

由于编译器的优化,在监视窗口中关于B调用的虚函数并不能显示完全,所以需要我们自己写一个打印虚表的函数 以上是单继承的模型 多继承中子集将虚函数存放在第一个继承的虚函数表中

#include<iostream> using namespace std; typedef void(*V_FUNC)(); class A { public: virtual void func1() { cout << "A::func1()" << endl; } virtual void func2() { cout << "A::func2()" << endl; } protected: int a; }; class B { public: virtual void func1() { cout << "B::func1()" << endl; } virtual void func3() { cout << "B::func3()" << endl; } protected: int b; }; class C:public A,public B { public: virtual void func1() { cout << "C::func1()" << endl; } virtual void func3() { cout << "C::func3()" << endl; } virtual void func4() { cout << "C::func4()" << endl; } protected: int c; }; void PrintVtable(int vtable) { int *vfArray = (int*)vtable; printf("vtable:0x%p\n", vfArray); for (size_t i = 0; vfArray[i] != 0; ++i) { printf("vfunc[%d]:0x%p->", i, vfArray[i]); V_FUNC f = (V_FUNC)vfArray[i]; f(); } cout << endl; } int main() { C c; PrintVtable(*((int*)&c));//A的虚表 PrintVtable(*(int*)((char*)&c + sizeof(A)));//B的虚表在A的虚表之后,相差sizeof(A) system("pause"); return 0; }

如func1(),A和C中都有,则进行虚函数重定义 3:多态的对象模型–菱形继承和菱形虚拟继承?

#include<iostream> using namespace std; typedef void(*V_FUNC)(); class A { public: virtual void func1() { cout << "A::func1()" << endl; } virtual void func2() { cout << "A::func2()" << endl; } protected: int a; }; class B:public A { public: virtual void func1() { cout << "B::func1()" << endl; } virtual void func3() { cout << "B::func3()" << endl; } protected: int b; }; class C:public A { public: virtual void func1() { cout << "C::func1()" << endl; } virtual void func4() { cout << "C::func4()" << endl; } protected: int c; }; class D :public B, public C { public: virtual void func5() { cout << "D::func5()" << endl; } protected: int d; }; void PrintVtable(int vtable) { int *vfArray = (int*)vtable; printf("vtable:0x%p\n", vfArray); for (size_t i = 0; vfArray[i] != 0; ++i) { printf("vfunc[%d]:0x%p->", i, vfArray[i]); V_FUNC f = (V_FUNC)vfArray[i]; f(); } cout << endl; } int main() { D d; PrintVtable(*((int*)&d)); PrintVtable(*(int*)((char*)&d + sizeof(B))); system("pause"); return 0; }

菱形虚拟继承

class A { public: virtual void func1() { cout << "A::func1()" << endl; } virtual void func2() { cout << "A::func2()" << endl; } public: int _a; }; class B : virtual public A { public: virtual void func1() { cout << "B::func1()" << endl; } virtual void func3() { cout << "B::func3()" << endl; } public: int _b; }; class C : virtual public A { virtual void func1() { cout << "C::func1()" << endl; } virtual void func3() { cout << "C::func3()" << endl; } public: int _c; }; class D : public B, public C { virtual void func1() { cout << "D::func1()" << endl; } virtual void func4() { cout << "D::func4()" << endl; } public: int _d; };

菱形虚拟继承(B,C共用A的虚表,各自有独立的虚表)

转载请注明原文地址: https://www.6miu.com/read-59999.html

最新回复(0)