大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
一. 多态的实现--虚表
创新互联基于成都重庆香港及美国等地区分布式IDC机房数据中心构建的电信大带宽,联通大带宽,移动大带宽,多线BGP大带宽租用,是为众多客户提供专业服务器托管报价,主机托管价格性价比高,为金融证券行业西部信息机房,ai人工智能服务器托管提供bgp线路100M独享,G口带宽及机柜租用的专业成都idc公司。1.多态就是多种形态。在C++中,对同一父类和子类构造出的不同对象发出同一条指令,需要它们完成不同的工作,就需要在父类和子类写出相同函数名的函数方法,并用虚函数区分它们。父类的指针/引用调用重写的虚函数,当父类指针/引用指向父类对象时调用的是父类的虚函数,指向子类对象时调用的是子类的虚函数。
2.虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了继承、虚函数(重写)的问题。在有虚函数的对象实例中都存在一张虚函数表,虚函数表就像一张地图,指明了实际应该调用的虚函数函数。
//带虚函数的类 class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virtual void func2() { cout << "Base::func2()" << endl; } private: int a; }; void Test1() { Base b1; }
3.带虚函数的类的模型结构
4.同一类的对象共用同一虚表
void Test2() { Base b1, b2, b3; }
二. 单继承&多继承的对象模型
1.单继承:
class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virtual void func2() { cout << "Base::func2()" << endl; } private: int a; }; class Derive :public Base { public: virtual void func1() { cout << "Derive::func1" << endl; } virtual void func3() { cout << "Derive::func3" << endl; } virtual void func4() { cout << "Derive::func4" << endl; } private: int b; }; typedef void(*FUNC) (); void PrintVTable(int* VTable) { cout << " 虚表地址>" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { printf(" 第%d个虚函数地址 :0X%x,->", i, VTable[i]); FUNC f = (FUNC)VTable[i]; f(); } cout << endl; } void Test1() { Base b1; Derive d1; int* VTable1 = (int*)(*(int*)&b1); int* VTable2 = (int*)(*(int*)&d1); PrintVTable(VTable1); PrintVTable(VTable2); }
2.多继承
class Base1 { public: virtual void func1() { cout << "Base1::func1" << endl; } virtual void func2() { cout << "Base1::func2" << endl; } private: int b1; }; class Base2 { public: virtual void func1() { cout << "Base2::func1" << endl; } virtual void func2() { cout << "Base2::func2" << endl; } private: int b2; }; class Derive : public Base1, public Base2 { public: virtual void func1() { cout << "Derive::func1" << endl; } virtual void func3() { cout << "Derive::func3" << endl; } private: int d1; }; typedef void(*FUNC) (); void PrintVTable(int* VTable) { cout << " 虚表地址>" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { printf(" 第%d个虚函数地址 :0X%x,->", i, VTable[i]); FUNC f = (FUNC)VTable[i]; f(); } cout << endl; } void Test1() { Derive d1; int* VTable = (int*)(*(int*)&d1); PrintVTable(VTable); // Base2虚函数表在对象Base1后面 VTable = (int *)(*((int*)&d1 + sizeof(Base1) / 4)); PrintVTable(VTable); }
三. 静态多态和动态多态
1.静态多态就是重载,因为是在编译期决议确定,所以称为静态多态。
2.动态多态就是通过继承重写基类的虚函数实现的多态,因为是在运行时决议确定,所以称为动态多态。
class Base { public: virtual void func1() { cout << "Base::func1" << endl; } virtual void func2() { cout << "Base::func2" << endl; } void display() { cout << "display()" << endl; } void display(int i) { cout << "display(int i)->" << i << endl; } private: int a; }; class Derive :public Base { public: virtual void func1() { cout << "Derive::func1" << endl; } virtual void func3() { cout << "Derive::func3" << endl; } virtual void func4() { cout << "Derive::func4" << endl; } private: int b; }; void func(Base& b) { b.func1(); b.display(); b.display(10); } void Test1() { Base b1; Derive d1; func(b1); func(d1); }
四. 菱形虚拟继承的对象模型
class A { public: virtual void FunTest1() { cout << "A::FunTest1()" << endl; } virtual void FunTest2() { cout << "A::FunTest2()" << endl; } private: int _a; }; class B1 :virtual public A { public: virtual void FunTest3() { cout << "B1::FunTest3()" << endl; } virtual void FunTest4() { cout << "B2::FunTest4()" << endl; } private: int _b1; }; class B2 :virtual public A { public: virtual void FunTest1() { cout << "B2::FunTest1()" << endl; } virtual void FunTest4() { cout << "B2::FunTest4()" << endl; } private: int _b2; }; class C :public B1, public B2 { public: virtual void FunTest1() { cout << "C::FunTest1()" << endl; } virtual void FunTest5() { cout << "C::FunTest5()" << endl; } private: int _c; }; void Test1() { C c; c.FunTest5(); }
可见,在虚拟继承中,无论是几重继承,最终子类的虚函数表总是与继承列表的第一个父类的虚函数表合并在一起,但是有覆盖的虚函数,自然去覆盖父类的同名虚函数,并合并在该父类的虚表中。
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。