C++中多态与多态对象模型
来源:互联网 发布:人物简笔画软件 编辑:程序博客网 时间:2024/06/05 11:31
一、什么是多态?
多态,其实就是多种形态——动态形态和静态形态(即重载)。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。通俗的说,就是两个函数同名,但参数列表不同,然后根据参数不同实现不同的功能, 即“一个接口,多种方法”。
构成多态条件有:虚函数的重写(覆盖)
父类(基类)的指针或者引用指向对象
在进行多态的单/多继承模型之前,我首先谈一下对虚函数,虚表的认识。
虚函数是C++实现多态的方式。类的成员函数前加virtual关键字,则这个成员函数称为虚函数。(虚函数的子类可以不写virtual)。
注意:只有类的非静态成员函数才能定义为虚函数
构造函数不能定义为虚函数(虚函数与虚表有关,虚表那时还未初始化好)
虚函数表是通过一块连续的内存存储虚函数地址的地址。
接下来我对函数的重载,重写和重定义做一下总结和比较。
重载举例
int Add(int a,int b);double Add(double a,double b);
重写举例
class Person{public : virtual void BuyTickets() { cout<<" 买票"<< endl; }protected : string _name ; // 姓名};class Student : public Person{public : virtual void BuyTickets() { cout<<" 买票-半价 "<<endl ; }protected : int _num ; //学号};int main(){ Student a; a.BuyTickets();//调用的是自己的BuyTickets(),而不是继承来自基类的 return 0;}
重定义(同名隐藏)举例
class Person{public : void BuyTickets() { cout<<" 买票"<< endl; }protected : string _name ; // 姓名};class Student : public Person{public : void BuyTickets() { cout<<" 买票-半价 "<<endl ; }protected : int _num ; //学号};int main(){ Student a; a.BuyTickets();//调用的是派生类自己重定义的BuyTickets(),而不是继承来自基类的 return 0;}
二、多态的单继承模型
#include<iostream>#include<assert.h>#include<windows.h>using namespace std;typedef void(*Func);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<<"Base::Func1"<<endl; } virtual void Func3() { cout<<"Base::Func3"<<endl; } virtual void Func4() { cout<<"Base::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 b2; int* VTable1 = (int*)(*(int*)&b1); int* VTable2 = (int*)(*(int*)&b2); PrintVTable(VTable1 ); PrintVTable(VTable2 );}int main(){ Test1(); return 0; system("pause");}
可以看到派⽣类Derive::func1重写基类Base::func1,覆盖了相应虚表位置上的函数。
ps:可以看到这⾥没有看到派⽣类Derive中的func3和func4,这两个函数就放在func2
的后⾯,这⾥没有显⽰是VS的问题(bug)
单继承对象模型
多重继承中,子类会同时重写多个父类中相同的函数,并且子类将自己的虚函数存放在第一个继承的虚函数表中。子类没有自己的虚表,继承第一个父类的虚表。
三:多态的多继承模型
#include<iostream>#include<assert.h>#include<windows.h>using namespace std;typedef void(*Func);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 );}int main(){ Test1(); return 0; system("pause");}
四、菱形继承和菱形虚拟继承
菱形继承对象模型
Assistant的对象中有两份Person成员
菱形继承存在二义性和数据冗余的问题
class Person{public : string _name ; // 姓名};class Student : public Person{protected : int _num ; //学号};class Teacher : public Person{protected : int _id ; };class Assistant : public Student, public Teacher{protected : string _majorCourse ; // 主修课程};void Test (){ Assistant a ; a.Student ::_name = "xxx"; a.Teacher ::_name = "yyy";}
菱形虚拟继承对象模型
#include<iostream>#include<assert.h>#include<windows.h>using namespace std;typedef void(*Func);class A { public: virtual void f1() { cout<<"A::f1"<<endl; } virtual void f2() { cout<<"A::f2"<<endl; } public: int _a; }; class B : virtual public A { public: virtual void f1() { cout<<"B::f1"<<endl; } virtual void f3() { cout<<"B::f3"<<endl; } public: int _b; }; class C : virtual public A { public: virtual void f1() { cout<<"C::f1"<<endl; } virtual void f3() { cout<<"C::f3"<<endl; } public: int _c; }; class D : public B, public C { public: virtual void f1() { cout<<"D::f1"<<endl; } virtual void f4() { cout<<"D::f4"<<endl; } public: int _d; }; typedef void(*V_FUNC)(); void PrintVTable(int* vtable) { printf("vtable:0x%p\n", vtable); int** ppVtable= (int**)vtable; for (size_t i = 0; ppVtable[i] != 0; ++i) { printf("vtable[%d]:0x%p->", i,ppVtable[i]); V_FUNC f = (V_FUNC)ppVtable[i]; f(); } cout<<"---------------------------------------------------"<<endl; } int main() { D d; d.B::_a = 1; d._b = 2; d.C::_a = 3; d._c = 4; d._d = 5; cout<<sizeof(B)<<endl; //B PrintVTable(*((int**)&d)); // C PrintVTable(*((int**)((char*)&d+sizeof(B)-sizeof(A)))); // A PrintVTable(*((int**)((char*)&d+sizeof(D)-sizeof(A)))); return 0; }
- C++中多态与多态对象模型
- 多态与对象模型
- 【C++】多态及其对象模型
- 【c++】多态&多态对象模型
- C++_多态&多态的对象模型
- 多态对象模型
- Objective-C对象模型
- Objective-C对象模型
- objective C 对象模型
- C ++ 对象模型
- Objective-C 对象模型
- 【C++】对象模型
- Objective-C对象模型
- C++对象模型之继承与多态的探索
- Objective-C的对象模型与运行时
- 多态&多态对象模型
- 多态&多态对象模型
- 多态及其对象模型
- concurrenthashmap 原理
- Encountered "lili" at line 26, column 12. Was expecting one of: <NEWLINE>
- input即时监听
- 相机动画与射线
- 28-包含
- C++中多态与多态对象模型
- 多校联合第三次题解(网页打不好开,扒下来看)
- Python 使用 os.fork() 创建子进程
- 29-动画
- 运营——线上引流9大方法
- 30-依赖注入
- Java 并发开发:Lock 框架详解
- 模块化操作
- 数据库原理—超键、候选键、主键、外键