一个例子说明虚函数
来源:互联网 发布:理光软件研究所 户口 编辑:程序博客网 时间:2024/05/17 18:40
一、虚函数的基础知识
虚函数的定义,调用(外部函数的指针或引用,成员函数),构造函数和析构函数中调用虚函数,虚析构函数
赋值兼容,构造函数的重载,构造函数的初始化列表
见代码:
#include<iostream>using namespace std;class Base{public:Base():m(1),n(m+1){Display();} //构造函数中调用虚函数时自己的虚函数Base(int x,int y):m(x),n(y){}void setxy(int x,int y){m=x+1;n=y+1;}virtual void Display(){cout<<"m*n="<< m*n<<endl;}void fun(){cout<<"成员函数访问虚函数:";Display();}virtual ~Base(){cout<<"析构函数base"<<endl;}private:int m;int n;};class Subclass : public Base{public:Subclass(int x,int y,int r1):Base(x,y),r(r1){Display();} //继承构造函数void setxyr(int x,int y,int r){setxy(x,y);r=r;} //继承成员函数void Display(){cout<<"sub--->"<<r*r<<",";Base::Display();}~Subclass(){cout<<"析构函数Subclass"<<endl;}private:int r;};void print(Base & p){cout<< "外部函数中使用引用调用虚函数:";p.Display();}void print2(Base *p){cout<< "外部函数中使用指针调用虚函数:";p->Display();}int main(){Base *bp;Subclass *sp;Base b1; //构造函数Base b(3,4); //构造函数,有虚函数bp = &b;Subclass s(3,4,2); //构造函数,有虚函数sp = &s;b1.setxy(7,8);s.setxy(4,5);s.setxyr(4,5,2);b1 = s; //赋值兼容bp = sp; print(b1); //外部函数中的虚函数,指向定义对象b1print(s);print2(bp);print2(sp);b1.fun(); //成员函数访问虚函数s.fun();b1.Display();b.Display();s.Display();delete bp; //虚析构函数,指向基类的指针,调用适当的析构函数,先调用派生类system("pause");}
二、虚函数的实现机制
虚函数时如何实现的呢?这和编译有关。下面就来具体了解虚函数的编译过程。主要涉及要两个概念:虚函数表(vtbl)、虚函数表指针(vptr)。
虚函数表主要是一个类的虚函数的地址表。这张表解决了继承、覆盖的问题,保证真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。
在C++的标准规格说明书中说到,编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证正确取到虚函数的偏移量)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。
0 0
- 一个例子说明虚函数
- 说明JavaScript 函数间按值传参的一个例子
- C++ 一个例子说明.c_str()函数
- C++ 函数指针 一个例子说明一下ing
- 函数指针例子说明
- 虚函数的一个例子
- 一个例子说明贝叶斯定理
- Sqlserver常用函数例子说明
- Sqlserver常用函数例子说明
- Sqlserver常用函数例子说明
- Sqlserver常用函数例子说明
- 一个虚函数的简单例子
- 关于虚函数一个很好的例子
- 一个函数的例子
- stl(三)------这是一个MSDN中的一个关于map 中find函数的说明 很好的一个例子
- 用一个例子说明VBS语法
- 用一个例子说明什么是多态
- 一个例子试着说明算法
- 支付宝集成获取私钥与公钥
- vim——打开多个文件、同时显示多个文件、在文件之间切换
- Callable与Future的介绍
- block的循环引用
- 越狱计划之背包初步--01背包
- 一个例子说明虚函数
- LeetCode之Path Sum II
- 1094. The Largest Generation (25)
- 子网划分的两个例子 怎么算网络号和广播地址
- 同一个账号只能一处登录
- Equinox OSGi系列之一 Equinox入门
- 我的openwrt学习笔记(九):开发板访问虚拟机 ubuntu linux 文件方法
- 普元日记---HTML5底部遮罩层
- 如何处理word转pdf格式的转换