简体   繁体   English

纯虚拟函数是早期绑定(编译时)还是后期绑定(运行时)?

[英]Are pure virtual functions early binding (compile time) or late binding (run time)?

I see in various online resources that virtual functions are runtime bound. 我在各种在线资源中看到virtual functions受运行时限制。

However a pure virtual function must be implemented in a derived class. 但是,必须在派生类中实现pure virtual function So, it doesn't make sense to me why a vtable would be needed in that scenario. 因此,对于我而言,在这种情况下为什么需要一个vtable并没有意义。 Therefore I was wondering if a pure virtual function is bound at runtime or compile time. 因此,我想知道在运行时或编译时是否绑定了pure virtual function

If it is bound at runtime, is it just for the case that a pure virtual function has an implementation and the derived class calls the base implementation? 如果在运行时绑定它,是否仅适用于pure virtual function具有实现且派生类调用基本实现的情况? What happens if no implementation is provided? 如果没有提供实现会怎样? Does the compiler then inline the implementation? 编译器是否会inline实现?

As you already found out, virtual functions are resolved at runtime. 如您所知,虚拟函数在运行时已解析。 You need a vtable for this situation: 您需要针对这种情况的vtable:

class Parent {
 public:
  virtual void pure() = 0;
};

class Child : public Parent {
 public:
  void pure() {}
};

void do_pure(Parent& x){
   x.pure();
}

int main(){
  do_pure(Child());
}

The Child() instance is cast to a Parent when it is passed to do_pure . Child()实例被强制转换为Parent ,当它被传递给do_pure The vtable is then required for the line x.pure() to be able to locate the memory adress of the implementation of pure() . 然后,对于x.pure()行,需要vtable才能找到pure()实现的内存地址。

If Child wouldn't implement do_pure , this wouldn't compile, because the line x.pure() could only crash. 如果Child不实现do_pure ,则不会编译,因为x.pure()行只会崩溃。

All virtual functions need to have late binding. 所有virtual功能都需要具有后期绑定。

Imagine the following class hierarchy: 想象下面的类层次结构:

struct Base {
    virtual void foo() = 0;
    virtual ~Base() = default;
};

struct Child: public Base {
    void foo() override { std::cout << "I'm good!"; }
};

struct Grandchild: public Child {
    void foo() final { std::cout << "But I'm better!"; }
};

void fooCaller(const Base& b) {
    //Which foo() do I call here? Child::foo() or Grandchild::foo()?
    b.foo();
}

int main() {
    Grandchild g;
    fooCaller(g);
}

A virtual function remains virtual in all derived classes, which means you can override is anywhere you want (unless it's declared final at some point). virtual函数在所有派生类中仍是virtual函数,这意味着您可以覆盖所需的任何位置(除非在某些时候将其声明为final )。 Compiler cannot know which version will be in use. 编译器无法知道将使用哪个版本。

In theory, if we have virtual void foo() = 0; 从理论上讲,如果我们有virtual void foo() = 0; in Base and void foo() final; Basevoid foo() final; in Child , compiler could notice that there is only one possible implementation of foo and optimize it out of the vtable, but I never heard about any compiler doing that. Child ,编译器可能会注意到foo可能只有一种实现,并且可以通过vtable对其进行优化,但是我从未听说过有任何编译器这样做。
And such use case kind of defeats the purpose of pure virtual functions. 并且这种用例无法达到纯虚拟功能的目的。

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

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