zoukankan      html  css  js  c++  java
  • 多态的实现原理

    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++适合开发系统、驱动程序等的原因。

  • 相关阅读:
    config文件 反射方法
    模块"xxxx.dll"已加载,但对DllRegisterServer的调用失败,错误代码为 XXXXXXXXX
    多线程定时 每天执行
    监控windows服务,当服务停止后自动重启服务
    log4net使用(winform)
    sql 第 10条 到20条
    windows 服务
    安卓屏幕模拟器
    dg_MeetingRoom 居中显示
    sql 清空所有数据
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764244.html
Copyright © 2011-2022 走看看