繁体   English   中英

在c ++中禁用虚拟功能的动态绑定(虚拟表创建)

[英]Disable dynamic binding (virtual table creation) in c++ for virtual functions

我最近遇到了一个C ++面试问题让我非常好奇:

假设您错误地将某些C ++成员函数声明为虚拟,但是(可能出于性能原因)您希望阻止编译器为此函数创建v表。 也就是说,禁用动态功能绑定以支持静态绑定。

你会如何实现这一目标? 此外,是否有一些C ++ 11具体的方法呢?

我知道没有办法强迫C ++编译器禁用动态绑定,如果它支持这样一个选项(不是所有的C ++编译器都做,但大多数都是这样),就不能强迫它编译纯C语言。 然而,这有点像用洗澡水甩掉婴儿,因为它理论上禁用了不属于C的所有C ++功能。

当然,还有C ++ 11中引入的final标识符,它可以防止从类中进一步派生或覆盖虚拟成员。 严格来说,这并不妨碍动态调度 - 它解决了一个不同的问题。

避免动态绑定的含义(感知或实际)的一种方法是避免使用或编写具有虚拟成员函数的任何类,并且不创建类层次结构(即,不从具有虚函数的类派生)。 显然,如果没有正在运行的虚函数,则不需要虚函数调度,因此不需要动态绑定。

如果您知道对象的类型,则可以通过使用静态分派来避免使用动态绑定,即明确命名要调用的函数。 例如,假设我们有一个类Base ,它提供一个名为foo()public virtual成员和一个名为Derived的类,它继承自Base并覆盖foo() 然后以下避免进行动态调度;

 Base *b = new Derived;
 b->Base::foo();          //   static call;  will not call `Derived::foo()`
 b->Derived::Foo();       // incorrect static call.  Will not compile since b is a pointer to Base not Derived

 Derived *d = new Derived;
 d->Derived::foo();       // static call of Derived::foo()
 d->Base::foo();          // static call of Base::foo()

当然,如果使用对象的代码依赖于对象的ACTUAL类型的知识,或者依赖于被调用的foo()的特定变体,那么它的设计类型会破坏具有多态基类和其他类的目的。从中衍生出来的类。

在上面,编译器仍将支持虚函数调用(vtable等,如果现在编译器工作),这可能会影响创建和销毁对象的过程。

另一种避免动态分派(或绑定)的技术是使用模板(有时称为编译时多态)。 本质上,模板可以假定类型提供一些接口(或一组操作),并且将使用具有该接口的任何类型的变量。 例如;

 struct X
 {
      void foo();
 };

 template<class T> void func()
 {
      T x;          // relies on T being instantiable (and destructible)
      x.foo();      // relies on T having a member named foo()
 }

 // in some function somewhere where both X and func() are known to the compiler

 func<X>();

此类模板不需要类型T具有虚函数,因此不要依赖动态调度(绑定)。 但是,没有什么能阻止这样的模板函数与具有虚拟成员函数的类一起工作,因此这不会禁用动态绑定 - 它只允许程序员做出选择以避免使用动态绑定。

如果我在采访中被问到这个问题,我可能会指出上述所有问题,但是请不要说这个问题相当愚蠢。 一位熟悉C ++的面试官会意识到这一点,并且对你如何思考和解决这样一个问题感兴趣(毕竟管理层或客户经常要求现实世界的开发人员满足愚蠢或不切实际的要求,并且预计会变得机智足以避免告诉他们的经理或客户他们是愚蠢的)。 如果面试官在没有理解的情况下提出这个问题(或者没有面试小组的其他成员了解房间内的情况),我也不想与该雇主合作。

您可以通过禁用RTTI来避免开销...有一个编译时间开关。

一旦启用了RTTI禁用标志,对于dynamic_cast / typeid,不会有虚拟表分派的任何开销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM