美文网首页
一分钟教你真正搞明白C++多态

一分钟教你真正搞明白C++多态

作者: 黄老师精品IT课 | 来源:发表于2019-02-18 10:46 被阅读0次

有那么多讲C++多态的文章,但是却没有一个能真正看明白的,神秘的多态机制,究竟是如何实现的,看黄老师来如何教你?

我们先看两个类:


class A

{

public:

A() { a = 111; }

virtual void  fun1()

{

cout << " A::fun1" << endl;

}

virtual void fun2()

{

cout << " A::fun2" << endl;

}

int a;

};

class  B:public A

{

public:

B() { b = 222; }

virtual void  fun2()

{

cout << " B::fun2" << endl;

}

virtual void fun3()

{

cout << " B::fun3" << endl;

}

int b;

};


简单介绍下规则:

1. 首先对于含有virtual关键字的类(A  或  B), 该类的所有对象的内存的前四个字节(32位系统下),存放一个内存地址,根据这个地址可以访问到该类的虚函数表内存(表中的每一项都是一个函数地址 ,所以A中有两项  fun1  ,fun2 )。

2. 派生类(自己有virtual 或者 基类中有 virtual 关键字),  根据1规则,同样有一张虚函数表内存 ( 表中的每一项都是一个函数地址,按道理来说应该是四项   A类中的 fun1  ,fun2 , B类中的fun2, fun3 ,这个时候需要注意,派生类的fun2 会覆盖基类的fun2, 所以只有三项) 

用图解释如下:

作为一个最喜欢扒内存的黄老师而言,利用代码测试其内存结构,便能一清二楚!!!

#include <iostream> 

using namespace std;

typedef  void(*PFUN)();

class  A

{

public:

A() { a = 111; }

virtual void  fun1()

{

cout << " A::fun1" << endl;

}

virtual void fun2()

{

cout << " A::fun2" << endl;

}

int a;

};

class  B:public A

{

public:

B() { b = 222; }

virtual void  fun2()

{

cout << " B::fun2" << endl;

}

virtual void fun3()

{

cout << " B::fun3" << endl;

}

int b;

};

int main()

{

//根据多态我们知道,肯定调用的是B的fun2

//A  *p = new B;

//p->fun2();

cout << "---------------------------A的虚函数表--------------------------" << endl;

{

cout << "A类的大小 " << sizeof(A) << endl;

//测试A的虚函数表

A    a;

int *pA = (int *)&a;//a内存空间的首地址

cout << "4字节vtable指针"<<endl;

int * vptr = (int *)(*pA); // a内存空间的 前4个字节 存放的内容是  虚函数表的地址

PFUN  afun1 = (PFUN)vptr[0];

afun1();

PFUN  afun2 = (PFUN)vptr[1];

afun2();

cout <<"4字节a成员"<< *(pA + 1)<<endl;  //成员变量a的内容

}

cout << "---------------------------B的虚函数表--------------------------" << endl; 

{

cout << "B类的大小 " << sizeof(B) << endl;

//测试B的虚函数表

B    b;

int *pB = (int *)&b;//b内存空间的首地址

cout << "4字节vtable指针" << endl;  //成员变量a的内容

int * vptr = (int *)(*pB); // b内存空间的 前4个字节 存放的内容是  虚函数表的地址

PFUN  bfun1 = (PFUN)vptr[0];

bfun1();

PFUN  bfun2 = (PFUN)vptr[1];

bfun2();

PFUN  bfun3 = (PFUN)vptr[2];

bfun3();

cout << "4字节a成员" << *(pB + 1) << endl;  //成员变量a的内容

cout << "4字节b成员" << *(pB + 2) << endl;  //成员变量b的内容

}

}

测试结果与示意图一样:

相关文章

  • 一分钟教你真正搞明白C++多态

    有那么多讲C++多态的文章,但是却没有一个能真正看明白的,神秘的多态机制,究竟是如何实现的,看黄老师来如何教你? ...

  • C++ 的多态(Polymorphism), virtual f

    多态 c++支持两种多态,编译时多态和运行时多态但其实编译时多态根本不是真正的多态,编译时多态就是函数的重载,ov...

  • 深刻剖析之c++博客文章

    三大特性 封装、继承、多态 多态 C++ 虚函数表解析C++多态的实现原理 介绍了类的多态(虚函数和动态/迟绑定)...

  • 多态的C++实现

    多态的C++实现 1 多态的原理 什么是多态?多态是面向对象的特性之一,只用父类指针指向子类的对象。 1.1 多态...

  • iOS绘图

    ios阶段算法回调多态(观察者模式)把多态真正明白上一大台阶程序设计设计模式if else少出 创建UIBezie...

  • C++第六篇多态

    C++中的多态性分为编译时多态性和运行时多态性,编译时多态通过函数重载和模板体现,运行多态通过虚函数体现编译、连接...

  • cmake 的正确打开方式

    用了那么多年 c++,今天才搞明白 cmake 该怎么用…… cmake 是一个跨平台的 c++ 构建工具,与 m...

  • 面试题目收集总结

    C++: 多态: 多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载) c语言和c++有什么区别?(...

  • C++的多态

    C++三大特性:封装、继承和多态。其中最好理解的就是封装了,继承作为C++面向对象的特征也不难理解,那么多态,应该...

  • 实现golang语言的多态

    如何实现golang语言的多态? C++里面有多态是其三大特性之一,那么golang里面的多态我们该怎么实现? g...

网友评论

      本文标题:一分钟教你真正搞明白C++多态

      本文链接:https://www.haomeiwen.com/subject/alnbeqtx.html