zoukankan      html  css  js  c++  java
  • c++对象虚表

    虚表(virtual table)

    The virtual table is actually quite simple, though it’s a little complex to describe in words. First, every class that uses virtual functions (or is derived from a class that uses virtual functions) is given it’s own virtual table. This table is simply a static array that the compiler sets up at compile time. A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this table is simply a function pointer that points to the most-derived function accessible by that class.

    带有虚函数的类都有自己的虚表,虚表是编译器在编译时就确定的一个静态数组。虚表中包含每个虚函数的一个入口(函数指针),且这个函数指针是对象能访问到最近的一个函数指针。

    Second, the compiler also adds a hidden pointer to the base class, which we will call *__vptr. *__vptr is set (automatically) when a class instance is created so that it points to the virtual table for that class. Unlike the *this pointer, which is actually a function parameter used by the compiler to resolve self-references, *__vptr is a real pointer. Consequently, it makes each class object allocated bigger by the size of one pointer. It also means that *__vptr is inherited by derived classes, which is important.

    编译器会为基类设置一个隐藏的指针(*__vptr), 该指针是在类实例化时自动设置指向类的虚表的。

    1、在进入构造函数时,虚表已经构建完成。

    2、虚构时,虚表可以回滚。

    3、虚表与虚表指针的区别:每个类只有一个虚表,每个对象实例都有个虚表指针。

    如下:

     1 #include "stdafx.h"
    2 #include <iostream>
    3
    4 class CBase
    5 {
    6 public:
    7 CBase()
    8 {
    9 std::cout<<"CBase::CBase()"<<std::endl;
    10 print();
    11 //print1();
    12 }
    13 virtual ~CBase()
    14 {
    15 std::cout<<"CBase::~CBase()"<<std::endl;
    16 print();
    17 }
    18 //virtual void print1() = 0;
    19 virtual void print()
    20 {
    21 std::cout<<"CBase::print()"<<std::endl;
    22 //print1();
    23 }
    24 };
    25
    26 class CDerived : public CBase
    27 {
    28 public:
    29 CDerived()
    30 {
    31 std::cout<<"CDerived::CDerived()"<<std::endl;
    32 print();
    33 }
    34
    35 virtual ~CDerived()
    36 {
    37 std::cout<<"CDerived::~CDerived()"<<std::endl;
    38 print();
    39 }
    40
    41 virtual void print()
    42 {
    43 std::cout<<"CDerived::print()"<<std::endl;
    44 }
    45
    46 virtual void print1()
    47 {
    48 std::cout<<"CDerived::print1()"<<std::endl;
    49 }
    50 };
    51
    52 void DoPrint(CBase* pBase)
    53 {
    54 pBase->print();
    55 }
    56 int _tmain(int argc, _TCHAR* argv[])
    57 {
    58 CBase* pBase = new CBase;
    59 CDerived* pDerived = new CDerived;
    60 CBase* pBase1 = pDerived;
    61
    62 std::cout<<"---------"<<std::endl;
    63 DoPrint(pBase);
    64 DoPrint(pDerived);
    65 DoPrint(pBase1);
    66 std::cout<<"---------"<<std::endl;
    67
    68 delete pBase;
    69 delete pDerived;
    70
    71 return 0;
    72 }

      输出:

    CBase::CBase()

    CBase::print()

    CBase::CBase()

    CBase::print()

    CDerived::CDerived()

    CDerived::print()

    ---------

    CBase::print()

    CDerived::print()

    CDerived::print()

    ---------

    CBase::~CBase()

    CBase::print()

    CDerived::~CDerived()

    CDerived::print()

    CBase::~CBase()

    CBase::print()

  • 相关阅读:
    贪心——poj百炼3468:电池寿命
    贪心——部分背包
    C++编程规范
    调和级数求和
    人工神经网络
    Latex各种符号
    poj1088 滑雪,dp
    数据挖掘建模过程
    Java MyEclipse:The type java.lang.CharSequence cannot be resolved. It is indirectly referen
    Java调用阿里云短信接口发送手机验证码
  • 原文地址:https://www.cnblogs.com/coderyoyo/p/2132626.html
Copyright © 2011-2022 走看看