Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is more a follow up on the comments from this <a href="https://stackoverflow.com/questions/2238928/why-do-we-actually-have-virtual-functions/2239065#2239065">answer</a> than an answer by itself.</p> <p><code>virtual</code> is a keyword that requests runtime dispatch for the method being declared and at the same time declares the method as one of the <em>overrides</em> (implemented pure virtual methods aside). The method being declared, and any method that shares the exact signature and name in the deriving hierarchy from this class down are <em>overrides</em>. When you call a virtual method through a parent pointer or reference, the runtime will call the most derived <em>override</em> in the hierarchy of the called upon object.</p> <p>When a method is not virtual, and the same method is defined later on in the hierarchy, you are <em>hiding</em> the parent method. The difference here is that when the method is being called through a base pointer or reference it will be calling the base implementation, while if it is being called in a derived object it will call the derived implementation. This, among other cases, is called hiding because the base and derived functions are unrelated, and having it defined in the derived class will <em>hide</em> the base version from a call:</p> <pre><code>struct base { virtual void override() { std::cout &lt;&lt; "base::override" &lt;&lt; std::endl; } void not_override() { std::cout &lt;&lt; "base::not_override" &lt;&lt; std::endl; } }; struct derived : base { void override() { std::cout &lt;&lt; "derived::override" &lt;&lt; std::endl; } void not_override() { std::cout &lt;&lt; "derived::not_override" &lt;&lt; std::endl; } }; int main() { derived d; base &amp; b = d; b.override(); // derived::override b.not_override(); // base::not_override d.not_override(); // derived::not_override } </code></pre> <p>The difference, and what is wrong in the answer by @erik2red is that <em>overrides</em> are intimately related to virtual functions and imply that there is a runtime dispatch mechanism in place that determines the <em>most derived</em> override to call. The behavior that is shown in the answer and associated to <em>override</em> is actually the behavior when there are no overrides but rather method hiding.</p> <p><strong>Other issues</strong></p> <p>The language allows for <em>pure virtual</em> methods with implementation. It does not say anything about what terminology should be used with them, but a pure virtual method will never be considered for runtime dispatch. The reason is that when a classes with pure virtual methods (even if implemented) are considered abstract classes, and you cannot instantiate an object of the class. Once you have a derived class that provides an implementation for that method, that implementation becomes the <em>final override</em> in the hierarchy. The class can now be instantiated, but the pure virtual method will not be called through the runtime dispatch mechanism.</p> <p>Virtual methods that are not the <em>final override</em>, as well as hided methods can be called if using the fully qualified name. In the case of virtual methods, using the fully qualified name disables the polymorphic dispatch mechanism for the call: <code>d.base::override()</code> will call the base implementation even if there are other <em>overrides</em> in deriving classes.</p> <p>A method can hide other methods in base classes even if the signatures do not match.</p> <pre><code>struct base { void f() {} }; struct derived : base { void f(int) {} }; int main() { derived d; // d.f() // error, derived::f requires an argument, base::f is hidden in this context } </code></pre> <p>As with <em>overrides</em>, <code>d.base::f()</code> will call the base version, not because it disables polymorphism --it does not, as the method is not declared virtual it will never have polymorphic behavior-- but because the full qualification tells the compiler where the method is, even if it was hidden by another method in the derived class.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload