• 多态的实现原理


    1、首先,思考一个问题。

    “多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定 ---- 这叫“动态联编”。“动态联编” 底是怎么实现的呢?

    //运行一段运用多态机制的程序
    class Base {
    public:
    	int i;
    virtual void Print() { cout << "Base:Print" ; }
    };
    
    class Derived : public Base{
    public:
    	int n;
    	virtual void Print() { cout <<"Drived:Print" << endl; }
    };
    
    int main() {
    	Derived d;
    	cout << sizeof( Base) << ","<< sizeof( Derived ) ;
    	return 0;
    }
    //程序运行输出结果: 8, 12 或:12,16
    //(也可能是其他,有对齐问题)
    

    为什么对象比预想的多了四个字节?真的是对齐问题嘛?这是多态实现的关键。

    2、多态实现的关键:虚函数表

    每一个有虚函数的类(或有虚函数的类的派生类)都有一个虚函数表,该类的任何对象中都放着虚函数表的指针(地址)。多出来的4(或者8个)个字节就是用来放虚函数表的地址的。
    虚函数表是编译器自动生成的,加到可执行文件中去的。当一个类装入内存时,和这个类关联的虚函数表也被装入了内存中。虚函数表中放着的就是这个类的所有虚函数在内存中的地址。
    通过虚函数表的地址可以找到虚函数表,然后通过虚函数的编码(名字)可以找到并调用虚函数。
    总之,有了这个表就能找到虚函数函数在内存中的地址。

    3、多态是怎么实现的?

    pBase = pDerived;
    pBase->Print();
    

    多态的函数调用语句被编译成:一系列根据基类指针所指向的(或基类引用所引用的)对象中存放的虚函数表的地址,在虚函数表中查找虚函数地址,并调用虚函数 的指令。
    在这里插入图片描述

    4、多态的利弊

    (1)优点
    有效的提高程序的可扩充性,节省程序员的时间。
    (2)缺点
    多态程序在运行期间会有额外的时间和空间上的开销。

    • 时间上:查虚函数标。
    • 空间上:每一个有虚函数的对象都会多出4个字节

    但是这时一个硬件便宜,人力贵,因此总体来讲是利大于弊。

    5、证实有虚函数的类的对象的前4(或者8)个字节存储着虚函数标的地址

    #include <iostream>
    using namespace std;
    class A
    {
    	public: virtual void Func()
    };
    
    class B:public A {
    	public: virtual void Func()
    };
    
    int main() {
    	A a;
    	A * pa = new B();
    	pa->Func();
    	//64位程序指针为8字节
    	long long * p1 = (long long* ) & a;
    	long long * p2 = (long long* ) pa;
    	* p2 = * p1;
    	pa->Func();
    	return 0;
    }
    /*输出:
    B::Func
    A::Func
    */
    

    此例证实了有虚函数的类的对象的前4(或者8)个字节存储着虚函数标的地址。
    从此例中也可以看出指针的力量。指针的好处:随便访问内存,针对一个变量,只访问它的一部分。但是没有指针概念的语言只能整体的访问一个变量。
    但是指针同时也有其弊端,即使得程序设计变得复杂,容易出错。但从效率上讲,指针会带来很大 好处。这也是为什么C++适合开发系统、驱动程序等的原因。

  • 相关阅读:
    史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)
    漫谈《大型网站技术架构》
    如何使用MongoDB+Springboot实现分布式ID?
    IOS UIView 01-View开始深入 绘制像素到屏幕上
    IOS 多线程04-GCD详解 底层并发 API
    IOS 多线程05-OperationQueue 、GCD详解
    IOS 多线程02-pthread 、 NSThread 、GCD 、NSOperationQueue、NSRunLoop
    IOS 公共类-数字处理
    React Native02-开始运行 Android篇
    React Native01-开始 Windows环境安装配置篇
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764244.html
Copyright © 2020-2023  润新知