Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 替代虚拟函数调用实现?_C++_Virtual Functions_Vtable_Vptr - Fatal编程技术网

C++ 替代虚拟函数调用实现?

C++ 替代虚拟函数调用实现?,c++,virtual-functions,vtable,vptr,C++,Virtual Functions,Vtable,Vptr,C++通过虚拟机制支持动态绑定。但据我所知,虚拟机制是编译器的一个实现细节,标准只是指定了在特定场景下应该发生的行为。大多数编译器通过虚拟表和虚拟指针实现虚拟机制。这与虚拟指针和表的实现细节无关。我的问题是: 除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟函数的动态分派?据我所知,大多数(读G++,MicrosoftVisualStudio)是通过虚拟表、指针机制实现的。那么实际上还有其他编译器实现吗 任何仅具有虚拟函数的类的sizeof都将是该编译器上指针的大小(vptr

C++通过虚拟机制支持动态绑定。但据我所知,虚拟机制是编译器的一个实现细节,标准只是指定了在特定场景下应该发生的行为。大多数编译器通过虚拟表和虚拟指针实现虚拟机制。这与虚拟指针和表的实现细节无关。我的问题是:

  • 除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟函数的动态分派?据我所知,大多数(读G++,MicrosoftVisualStudio)是通过虚拟表、指针机制实现的。那么实际上还有其他编译器实现吗
  • 任何仅具有虚拟函数的类的
    sizeof
    都将是该编译器上指针的大小(vptr inside
    this
    )。既然虚拟指针和TBL机制本身就是编译器实现,那么我上面所说的这句话会永远正确吗
  • 我认为除了vptr/vtable之外,没有任何现代编译器采用这种方法。事实上,很难找到一个不仅仅是效率低下的东西

    然而,在这种方法中,仍有相当大的设计权衡余地。可能特别是关于如何处理虚拟继承。因此,定义这个实现是有意义的

    如果你对这类东西感兴趣,我强烈建议你阅读

  • 类的大小取决于编译器。如果你想要可移植的代码,不要做任何假设

  • 我从未听说或见过任何编译器使用任何替代实现。vtables如此流行的原因是,它不仅是最有效的实现,而且是最简单的设计和最明显的实现

  • 在几乎所有您想使用的编译器上,这几乎肯定是正确的。然而,这并不能保证,也不总是正确的——你不能依赖它,即使它几乎总是如此。你最喜欢的编译器也可以改变它的对齐方式,增加它的大小,为了好玩,而不用告诉你。从内存中,它还可以插入任何调试信息和它喜欢的任何内容

  • 除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟机制?据我所知,大多数(读g++,MicrosoftVisualStudio)是通过虚拟表、指针机制实现的。那么实际上还有其他编译器实现吗

    我知道C++编译器使用的是什么,不过你可能会发现读二叉树调度很有意思。如果您对以任何方式利用虚拟分派表的期望感兴趣,那么您应该知道编译器有时可以在编译时解析虚拟函数调用,因此可能不会查阅该表

    任何只有一个虚函数的类的sizeof都将是该编译器上指针的大小(this中的vptr),因此假设虚ptr和tbl机制本身就是编译器实现,那么我上面所说的这句话是否总是正确的

    假设没有具有自己的虚拟成员的基类,也没有虚拟基类,那么这极有可能是真的。可以设想其他方法,例如整个程序分析只显示类继承权中的一个成员,以及切换到编译时分派。如果需要运行时分派,很难想象为什么任何编译器都会引入进一步的间接寻址。尽管如此,该标准并没有明确规定这些内容,因此实现可能会有所不同,或者将来会有所不同

    除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟机制?据我所知,大多数(读g++,MicrosoftVisualStudio)是通过虚拟表、指针机制实现的。那么实际上还有其他编译器实现吗

    我所知道的所有当前编译器都使用vtable机制

    这是一个可能的优化,因为C++是静态类型检查的。 在一些更具动态性的语言中,在基类链上有一个动态搜索,从对象的最派生类开始搜索虚拟调用的成员函数的实现。例如,这就是它在最初的Smalltalk中的工作原理。C++标准描述了虚拟调用的效果,就好像使用了这样的搜索。 在20世纪90年代的Borland/Turbo Pascal中,这种动态搜索用于查找Windows API“窗口消息”的处理程序。我认为在Borland C++中可能也是一样的。它是对普通vtable机制的补充,仅用于消息处理程序

    如果它在Borland /Turbo C++中使用——我记不起来了,那么它支持一个语言扩展,允许你把消息ID和消息处理函数联系起来。 任何只有一个虚函数的类的sizeof都将是该编译器上指针的大小(this中的vptr),因此假设虚ptr和tbl机制本身就是编译器实现,那么我上面所说的这句话是否总是正确的

    从形式上说,没有(即使假设有vtable机制),这取决于编译器。由于该标准不需要vtable机制,因此它没有说明每个对象中vtable指针的位置。其他规则允许编译器在末尾自由添加填充,即未使用的字节

    但在实践中也许是这样

    然而,这不是你应该依赖的东西,也不是你需要依赖的东西。但在另一个方向上,您可以要求这样做,例如,如果您正在定义ABI。然后
    if (auto frobj = dynamic_cast<FrequentlyOccurringType>(obj)) {
        frobj->FrequentlyOccurringType::method();  // static dispatch on hot path
    } else {
        obj->method();  // vtable dispatch on cold path
    }
    
    Local anInfo->x = 5
    Local anInfo->_get_x() = 5
    Local anInfo->y = A
    Local anInfo->_get_y() = B
    {An instance of class info at address 0092E318
    
    }