C++对象在内存中的存放方式

    xiaoxiao2021-03-25  160

    对象占有一定的内存,该内存上存放的是该对象的相关数据,按先后顺序如下:

    1、虚表指针:如果该类有虚函数的话,将存放虚表指针,该指针指向该类的虚函数表,即指向表中的第一个元素。续表中存放的是该类虚函数的地址;

    2、基类数据成员(如果有基类);

    3、自己的数据成员;

    对象在调用成员函数时的方式:

    1、调用非虚成员函数:其实相当于是非成员函数调用,实现根据对象类型找到该对象所属类,并在类中查找被调用的成员函数,查找到后调用;

    实际上,类的成员函数都有一个隐藏的参数,this指针,成员函数的调用在编译时就被替换为一个非成员函数的调用,不涉及对象的具体内容,只涉及对象的类型,是一种静态的绑定关系,即根据调用者所属类型确定调用哪个函数。如:

    a.fun()—>fun(&a)

    编译器根据a所属的类查找到要调用的函数,然后将成员函数的调用转变为一个非成员函数的调用;

    2、调用虚函数:实现根据虚表找到该类拥有的虚函数地址,然后查找到被调用的虚函。由于需要用到虚表,而虚表是保存在每个对象中的,因此必须要根据对象中存储的虚表进行函数调用,这就无法在编译时实现,只能是运行时进行,因此一种动态绑定关系,即根据调用者内容确定调用哪个函数。

    因此,当用一个基类指针指向一个派生类对象的时候:

    Class Base

    {

    /*构造、析构函数省略*/

    virtual void fun1()

    {

    cout<<"call Base::fun1";

    }

    void fun2()

    {

    cout<<"call Base::fun2";

    }

    Class Derived : public Base

    {

    /*构造、析构函数省略*/

    virtual void fun1()

    {

    cout<<"call Derived::fun1";

    }

    void fun2()

    {

    cout<<"call Base::fun2";

    }

    }

    Derived D;

    Base* pBase = &D;

    例一:pBase->fun1();

    上面的函数调用调用的是Derived的fun,因为虽然指针是基类的指针,但是在查找虚表时用到的是对象的内存上的虚表地址,而该对象是派生类,虚表中的函数是派生类的虚函数; 

    例二:pBase->fun2();

    上面这个调用调用的是基类的fun2,因为非虚函数的调用只看调用者的类型,不涉及调用者实际在内存上的信息;

    转载请注明原文地址: https://ju.6miu.com/read-1782.html

    最新回复(0)