Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>In your first example:</p> <pre><code> x=(xxx*) &amp;y1; //one class pointer containing another class object address x-&gt;f(); x-&gt;g(); </code></pre> <p>The variable <code>x</code> is ACTUALLY pointing at a class <code>yyy</code> which has nothing to do with class <code>xxx</code>. The fact that <code>f()</code> is declared in both and is the ONLY virtual function makes it happen to work. Since <code>g()</code> is a virtual function in class <code>xxx</code>, but not a virtual function in <code>yyy</code>, the compiler will generate code to call a the virtual function <code>g()</code> with some garbage from whatever happens to be after <code>f()</code> in the table of virtual functions (aka <code>vtable</code>) [Exactly how virtual functions are implemented is of course an implementation detail, but it's fair to expect that there is some sort of "table" of functions stored somewhere for each class]. </p> <p>It would give you even more interesting results if your <code>yyy</code> was declared like this:</p> <pre><code>class yyy{ //yyy has no relation with xxx at this context public: virtual void g(){cout&lt;&lt;"g in yyy"&lt;&lt;endl;} //virtual function but no relation with xxx class void f(){cout&lt;&lt;"f in yyy"&lt;&lt;endl;} }; </code></pre> <p>It will tell you that it got to "g in yyy" as the result of the call to <code>f()</code>, and then fail on calling <code>g()</code>... Becasue the way that virtual functions work isn't that they are called based on their names, but their "order" in the class [again, exactly how this works is an implementation detail, and since we are dealing with "undefined behaviour", the compiler is also allowed to print the "The answer is 42" in flashing red text on the screen or sound like an ambulance on an emergency call - but that is less likely to happen than what I just described in a typical C++ compiler implementation]. </p> <p>In your second case, since the <code>virtual</code> of <code>xxx</code> is inherited into <code>yyy</code>, the function <code>g()</code> is virtual in <code>yyy</code> as well, as "it works as you expect it", because what you are doing is exactly what you are supposed to do. </p> <p>Note also that there are C++ style casts that help you avoid making these sort of mistakes - if you do it wrong, it will give an error message when compiling (<code>static_cast</code>), or if you use <code>dynamic_cast</code> in a place where the compiler can't determine the type at compile time, it gives <code>nullptr</code> as a result, which is an obvious indicator that you got it wrong. </p>
 

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