C++多态与虚函数
来源:互联网 发布:硬盘序列号查询软件 编辑:程序博客网 时间:2024/06/05 03:11
多态是C++的三大特性之一
多态分为 动态多态,静态多态;其中静态多态分为,函数重载,泛型编程;动态多态为虚函数。
静态多态是在编译时就确定的,动态多态是在程序运行过程中确定。
本篇文章主要讨论虚函数:虚函数通过基类的引用或者基类指针来调用。
class Base{public:virtual void Funtest1(void){cout<<"Base::Funtest1()"<<endl;}virtual void Funtest2(){cout<<"Base::Funtest2()"<<endl;}int _b;};
sizeof(Base); //结果为8
这个结果说明在base这个类中多出了四个字节那么这四个字节是干什么的?
由此可以得到多出来的四个字节是指向虚函数的地址表的简称虚表
多重继承中对象的模型
class Base1 { public: virtual void Funtest1() { cout<<"Base1::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"Base1::Funtest2()"<<endl; } int _b1; }; class Base2 { public: virtual void Funtest3() { cout<<"Base2::Funtest3"<<endl; } virtual void Funtest4() { cout<<"Base2::Funtest4"<<endl; } int _b2; }; class Devire:public Base1,public Base2 { public: void Funtest2() { cout<<"Devire::Funtest2()"<<endl; }void Funtest4(){cout<<"Devire::Funtest2()"<<endl;} int _d; };
void test(){Devire d;d._b1 = 1;d._b2 = 2;d._d = 3;}
由此可见在多继承关系中派生类的对象模型中按照继承关系的声明顺序在内部对对象进行排序最后是派生类自己的成员。
其中继承自Base1中的虚函数用Base1的虚表,继承自Base2中的虚函数用Base2的虚表
重写过的虚函数有新生成的虚函数地址,没有重写的虚函数从原来的虚表中拷贝一份地址放入虚表。
菱形继承
class Base{public:virtual void Funtest(){cout<<"Base::Funtest()"<<endl;}int _b;};class Base1:public Base { public: virtual void Funtest1() { cout<<"Base1::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"Base1::Funtest2()"<<endl; } int _b1; }; class Base2:public Base { public: virtual void Funtest3() { cout<<"Base2::Funtest3"<<endl; } virtual void Funtest4() { cout<<"Base2::Funtest4"<<endl; } int _b2; }; class Devire:public Base1,public Base2 { public: void Funtest2() { cout<<"Devire::Funtest2()"<<endl; }void Funtest4(){cout<<"Devire::Funtest2()"<<endl;} int _d; };void test1(Base1& b){b.Funtest1();b.Funtest2();}void test(){Devire d;d.Base1::_b = 4;d.Base2::_b = 5d._b1 = 1;d._b2 = 2;d._d = 3;}
对于菱形继承在派生类中的对象模型与多继承相差不大也是按照声明顺序来排列派生类自己的成员在最后,但是有了数据冗余浪费了空间。
解决数据冗余问题引入虚继承
class Base{public:virtual void Funtest(){cout<<"Base::Funtest()"<<endl;}int _b;};class Base1:virtual public Base { public: virtual void Funtest1() { cout<<"Base1::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"Base1::Funtest2()"<<endl; } int _b1; }; class Base2: virtual public Base { public: virtual void Funtest3() { cout<<"Base2::Funtest3"<<endl; } virtual void Funtest4() { cout<<"Base2::Funtest4"<<endl; } int _b2; }; class Devire: public Base1,public Base2 { public: void Funtest2() { cout<<"Devire::Funtest2()"<<endl; }void Funtest4(){cout<<"Devire::Funtest2()"<<endl;} int _d; };void test1(Base1& b){b.Funtest1();b.Funtest2();}void test(){Devire d;d._b = 4;d._b1 = 1;d._b2 = 2;d._d = 3;}
通过测试得到结果图中绿色矩形框是偏移量表对其解引用的到的第一个值是虚表相对于对象的起始位置偏移0xfffffffc是-4的补码第二个是对象起始位置相对于_b的偏移
0 0
- C++_多态与虚函数
- C++_多态与虚函数
- 用C实现多态(重载与虚函数)
- C++:类的多态与虚函数的使用
- c++--多态性与虚函数
- [C++] 多态性与虚函数
- [C++]虚函数与纯虚函数
- c++-虚函数与纯虚函数
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- C02-程序设计基础提高班(C++)第13周上机任务-多态与虚函数
- C语言面向对象编程(三):虚函数与多态
- C语言面向对象编程(三):虚函数与多态
- C语言面向对象编程(三):虚函数与多态
- C语言面向对象编程之三:虚函数与多态
- C/C++虚函数与虚继承
- C++:虚函数与抽象类 zz
- C++Primer-虚函数与默认实参
- React.js 子组件调用父组件的方法
- Linux头文件和库文件搜索
- mybatis SQL语句复用
- ARM常用汇编指令
- React-Native or jspatch 热更新在苹果那里不行了
- C++多态与虚函数
- leetcode541 Reverse StringII java
- Spring集成
- SQL Server-字字珠玑,一纸详文,完全理解SERIALIZABLE最高隔离级别(基础系列收尾篇)
- jquery中attr和prop的区别
- requests包的安装
- java使用redis实现分布式锁
- Servlet和Jsp工作原理(转)
- java批量处理数组中元素后,返回处理结果的元素集合