C++多态,接触其实也没太长的时间。上课的时候老师总是不停的讲,多态可以实现利用一个基类对象调用不同继承类的成员函数。我就会觉得很伤脑筋,这个的原理到底是什么?是什么呢?

开始的时候我觉得自己应该能够把它的原理想出来,因为一直觉得关于这些高级语言的事情,不论看起来多么神奇,其实应该都是之前学的基础累积起来的。所以,我就自己想了一段时间————能够实现这样效果的只有 指针 了。

但是这个指针应该怎么定义呢?就算基类中本身定义了一个指针,可是继承类中被继承来的函数在利用基类的时候怎么告诉基类到底调用哪一个继承类的函数呢?真的伤脑筋。

……

现在是开始这个博客的第二天,我终于可以开始继续写了——因为我开始自己调试观察虚函数。

OK,现在开始了:

首先:

一、没有继承的类

(1)段小小的代码:

class A
{
int x;
int y;
public:
virtual void out()
{
cout << x << y << endl;
cout<<"A"<<endl;
}
};
int main()
{
A a;
return 0;
}
十分明显这段程序中仅仅只有一个类,一个虚函数!现在我们一起来看看类A的成员到底如何分布的。



成员变量x和y存在。同时出现了 _vptr 。它是什么?没错儿就是虚函数表指针。也就是说这个_vptr就是指向虚函数表(或者理解它为指向,存有所有虚函数地址的一个数组的指针)的一个指针!

现在我们点开_vptr发现:



它里面仍然是一个指针但是这个是指向我们唯一的虚函数void out()的指针!

总结:

通过上面的观察,我们知道了虚函数是由虚函数表里面存储的地址通过寻址的方式来实现的。那么就意味着我们可以直接通过地址来调用函数!这里我们也可以通过一段代码验证我所述的是否为真。

首先我们要获得虚函数表指针:

int main()
{
A a;
int *_Avptr;
_Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为(int*)型。 return 0;
}

获得虚函数指针

int main()
{
A a;
int *_Avptr;
int *Varr;
_Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为int*型。
Varr = (int *)*(_Avptr);//获得虚函数指针。
return 0;
}

直接通过指针调用函数

```typedef void(*pFUNC)(void);//定义一个无返回值,无参数的指针型函数。
```
```
int main()
{
A a;
int *_Avptr;
int *Varr;
_Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为int型。
Varr = (int *)*(_Avptr);//获得虚函数指针。

pFUNC pfunc1 = (pFUNC)*Varr;//开始利用地址直接访问虚函数
pfunc1();
return 0;

}

###运行结果:
![](https://img2018.cnblogs.com/blog/1784621/201911/1784621-20191112185538732-616549306.png)

virtual void out()

{

cout << x << y << endl;

cout<<"A"<<endl;

}

输出内容和我们虚函数中写的函数需要我们输出的无异议。所以证明了我们之前的想法。
现在,对虚函数到底是怎么存在的应该没有什么问题了。

C++虚函数作用原理(一)——虚函数如何在C++语言逻辑中存在的更多相关文章

  1. 【C++】多态性(函数重载与虚函数)

    多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...

  2. c++ 虚函数和纯虚函数

    在你设计一个基类的时候,如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的.从设计的角度讲,出现在基类中的虚函数是接口,出现在派生类中的虚函数是接口的具体实现.通过这样的方法,就可以将对象 ...

  3. C++ - 虚基类、虚函数与纯虚函数

    虚基类       在说明其作用前先看一段代码 class A{public:    int iValue;}; class B:public A{public:    void bPrintf(){ ...

  4. C++中不能声明为虚函数的有哪些函数

    常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被o ...

  5. TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)

    手工找出来,对比一下,有助于VCL框架的理解.----------------------------------------------------------------------------- ...

  6. C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类

    类继承 在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生. 从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. //单继承的定义 class B:public A { ...

  7. C++ Primer--虚函数与纯虚函数的区别

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  8. C++ 虚函数与纯虚函数

    #include<iostream> #include<string> using namespace std; class A{ public: virtual void f ...

  9. c++中虚函数和纯虚函数定义

    只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声 ...

随机推荐

  1. C# Redis 缓存应用 主要代码及版本选择

    /// <summary> /// RedisManager类主要是创建链接池管理对象的 /// </summary> public class RedisManager { ...

  2. nexus私服库被误删如何恢复

    恢复步骤: 1,登录nexus服务器,找到nexus安装目录(默认/usr/local/下): 2,找到sonatype-work/nexus/trash 下找到你删除的库: 3,copy到指定的so ...

  3. sqlalchemy 的操作

    使用PyMySQL的前提: 1. 先建好表 2. 自己动手需要手动去写多条SQL语句 改进: 类 ------>  表 实例化 -> 数据 这种思想叫:ORM(Object Relatio ...

  4. iptables基本命令到深入

    1.关闭firewalld,安装iptables-server并启动服务 systemctl stop firewalld systemctl disable firewalld yun -y ins ...

  5. 【VS开发】CListCtrl控件使用

    为何调用了CListCtrl的InsertColumn却什么效果都没有?这个问题以前发现过,今天才清楚,那就是要把它的Style指定为LVS_REPORT.       具体做法如下:       假 ...

  6. prometheus+grafana监控Linux和kubernetes的例子

    1.安装和配置prometheus tar zxvf prometheus-.linux-amd64.tar.gz -C /usr/local/ ln -sv /usr/local/prometheu ...

  7. python标准库之shutil——可操作权限的文件操作库

    转载自:https://www.jb51.net/article/145522.htm shutil模块提供了许多关于文件和文件集合的高级操作,特别提供了支持文件复制和删除的功能. 文件夹与文件操作 ...

  8. pycharm中文专业版安装使用

    激活码 MTW881U3Z5-eyJsaWNlbnNlSWQiOiJNVFc4ODFVM1o1IiwibGljZW5zZWVOYW1lIjoiTnNzIEltIiwiYXNzaWduZWVOYW1lI ...

  9. DOS bcp

    C:\>bcp /?用法: bcp {dbtable | query} {in | out | queryout | format} 数据文件  [-m 最大错误数]             [ ...

  10. 第二章 impala基础使用

    第二章 impala基本使用 1.impala的使用 1.1.impala-shell语法 1.1.1.impala-shell的外部命令参数语法 不需要进入到impala-shell交互命令行当中即 ...