探索多态和多态对象模型—单一继承&多重继承
来源:互联网 发布:淘宝top api易语言sdk 编辑:程序博客网 时间:2024/05/16 00:54
1.什么是多态?
谈到多态,我们必须首先了解一下什么是虚函数。虚函数:在类的成员函数前加virtual关键字,把这个成员函数称为虚函数。
多态需满足两个条件:
子类的虚函数须覆盖(重写)父类的虚函数;(协变例外)
当使用基类的指针或引用调用重写的虚函数时,指向基类对象就调用基类的虚函数,指向派生类的对象就调用派生类的虚函数。
注:多态只与对象有关,与类型无关。
扩充:虚函数重写(覆盖):当派生类中定义的虚函数和基类中定义的虚函数完全相同的时候,则称派生类中的虚函数重写了基类中的虚函数。
协变:
class A{public: virtual A* func()---virtual A& func() { return this;---return *this; }};class B{public: virtual B* func()---virtual B& func() { return this;---return *this; }};
2.多态的对象模型
单一继承模型
typedef void(*FUNC) ();class First{public: First() :_f(1){} virtual void f(){ cout << "First::f()" << endl; } virtual void f1(){ cout << "First::f1()" << endl; }public: int _f;};class Second : public First{public: Second() :_s(2){} virtual void f(){ cout << "Second::f()" << endl; } virtual void f2(){ cout << "Second::f2()" << endl; } virtual void f3(){ cout << "Second::f3()" << endl; }public: int _s;};void Print(int *Vfptr){ cout << "虚表地址" << Vfptr << endl; for (int i = 0; Vfptr[i] != 0; ++i) { FUNC f = (FUNC)Vfptr[i]; cout << "[" << i << "]" << endl; f(); } cout << endl;}int main(){ First f; Second s; int *Vfptr1 = (int*)(*(int*)&f); int *Vfptr2 = (int*)(*(int*)&s); Print(Vfptr1); Print(Vfptr2); system("pause"); return 0;}
单一继承总结:
虚函数表一般放在最前面;
成员变量根据会根据继承关系按先后顺序排列;
当有虚函数覆盖时,派生类的虚函数会将虚函数表中的基类虚函数替换;
虚函数表最后一个为0/NULL。
多重继承模型:
class B1{public: B1() :_b1(1){} virtual void b(){ cout << "B1::b()" << endl; } virtual void b1(){ cout << "B1::b1()" << endl; }public: int _b1;};class B2 {public: B2() :_b2(2){} virtual void b(){ cout << "B2::b()" << endl; } virtual void b2(){ cout << "B2::b2()" << endl; } virtual void b3(){ cout << "B2::b3()" << endl; } virtual void b4(){ cout << "B2::b4()" << endl; }public: int _b2;};class D : public B1 , public B2{public: D() :_d(3){} virtual void b(){ cout << "D::b()" << endl; } virtual void b1(){ cout << "D::b1()" << endl; } virtual void b3(){ cout << "D::b3()" << endl; } virtual void b5(){ cout << "D::b5()" << endl; }public: int _d;};typedef void(*FUNC) ();//函数指针void Print(int *Vfptr){ cout << "虚表地址" << Vfptr << endl; for (int i = 0; Vfptr[i] != 0; ++i) { FUNC f = (FUNC)Vfptr[i]; cout << "[" << i << "]" << endl; f(); } cout << endl;}int main(){ D d; int *Vfptr1 = (int*)(*(int*)&d);//B2的虚函数表在B1虚函数表的下面,跳过B1虚函数才可以打印出B2的虚函数表 int *Vfptr2 = (int*)(*((int*)&d+sizeof(B1)/4)); Print(Vfptr1); Print(Vfptr2); system("pause"); return 0;}
D继承后B1,B2后,D类的实例化对象模型:
在VS2013下的运行结果(打印的虚函数表):
多重继承总结:
派生类会继承每个基类的虚函数表;
派生类的成员函数会放在第一个基类的虚函数表中;
成员变量的存储顺序是按照继承先后顺序存储;
派生类中有和基类中相同的虚函数,基类的虚表会被改变。
阅读全文
1 0
- 探索多态和多态对象模型—单一继承&多重继承
- C++对象模型之继承与多态的探索
- 探索多态模型—菱形继承和菱形虚拟继承
- C++对象模型---多态性的支持(单一继承下的多态)
- js单一继承和多重继承
- 多继承和多重继承
- 实现类和继承、多重继承和多态
- python进阶15:继承、多态和多重继承
- C++多重继承和虚拟继承对象模型、效率分析
- C++多重继承和虚拟继承对象模型、效率分析
- C++多重继承和虚拟继承对象模型、效率分析
- C++ - 多重继承和虚拟继承对象模型、效率分析
- 单一继承与多重继承
- 单一继承与多重继承
- 多重继承的对象模型
- c++多态对象模型:单继承,多继承
- 多态和继承(2)——多重继承、子类互为友元
- C++ 讲解:多继承和多重继承
- Mac Navicat for Mysql插入中文失败
- css 标题文字前面加小图标,如何使它们不错位?
- FreeMarker
- Python简单图片爬虫
- C语言详解(4)控制语句的注意事项
- 探索多态和多态对象模型—单一继承&多重继承
- 【C++】第10章 对象和类 知识点总结
- 02-线性结构1 两个有序链表序列的合并(15 分)
- 第1章 引论
- bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
- wget
- Hibernate的多对一
- Java——将单向链表按某值划分成左边小、中间相等、右边大的形式(基础问题)
- 【学习C++】学习C++ -> 一维数组