“Direct” vs “virtual” call to a virtual function

前端 未结 2 1238
旧时难觅i
旧时难觅i 2021-02-14 13:31

I am self-taught, and therefore am not familiar with a lot of terminology. I cannot seem to find the answer to this by googling: What is a \"virtual\" vs a \"direct\" call to a

2条回答
  •  太阳男子
    2021-02-14 13:40

    The answer to your question is different at different conceptual levels.

    • At conceptual language level the informal term "virtual call" usually refers to calls resolved in accordance with the dynamic type of the object used in the call. According to C++ language standard, this applies to all calls to virtual functions, except for calls that use qualified name of the function. When qualified name of the method is used in the call, the call is referred to as "direct call"

      SomeObject obj;
      SomeObject *pobj = &obj;
      SomeObject &robj = obj;
      
      obj.some_virtual_function(); // Virtual call
      pobj->some_virtual_function(); // Virtual call
      robj.some_virtual_function(); // Virtual call
      
      obj.SomeObject::some_virtual_function(); // Direct call
      pobj->SomeObject::some_virtual_function(); // Direct call
      robj.SomeObject::some_virtual_function(); // Direct call
      

      Note that you can often hear people say that calls to virtual functions made through immediate objects are "not virtual". However, the language specification does not support this point of view. According to the language, all non-qualified calls to virtual functions are the same: they are resolved in accordance with the dynamic type of the object. In that [conceptual] sense they are all virtual.

    • At implementation level the term "virtual call" usually refers to calls dispatched through some implementation-defined mechanism, that implements the standard-required functionality of virtual functions. Typically it is implemented through Virtual Method Table (VMT) associated with the object used in the call. However, smart compilers will only use VMT to perform calls to virtual functions when they really have to, i.e. when the dynamic type of the object is not known at compile time. In all other cases the compiler will strive to call the method directly, even if the call is formally "virtual" at the conceptual level.

      For example, most of the time, calls to virtual functions made with an immediate object (as opposed to a pointer or a reference to object) will be implemented as direct calls (without involving VMT dispatch). The same applies to immediate calls to virtual functions made from object's constructor and destructor

      SomeObject obj;
      SomeObject *pobj = &obj;
      SomeObject &robj = obj;
      
      obj.some_virtual_function(); // Direct call
      pobj->some_virtual_function(); // Virtual call in general case
      robj.some_virtual_function(); // Virtual call in general case
      
      obj.SomeObject::some_virtual_function(); // Direct call
      pobj->SomeObject::some_virtual_function(); // Direct call
      robj.SomeObject::some_virtual_function(); // Direct call
      

      Of course, in this latter sense, nothing prevents the compiler from implementing any calls to virtual functions as direct calls (without involving VMT dispatch), if the compiler has sufficient information to determine the dynamic type of the object at compile time. In the above simplistic example any modern compiler should be able to implement all calls as direct calls.

提交回复
热议问题