SI
SI
discoversearch

We've detected that you're using an ad content blocking browser plug-in or feature. Ads provide a critical source of revenue to the continued operation of Silicon Investor.  We ask that you disable ad blocking while on Silicon Investor in the best interests of our community.  If you are not using an ad blocker but are still receiving this message, make sure your browser's tracking protection is set to the 'standard' level.
Technology Stocks : BORL: Time to BUY! -- Ignore unavailable to you. Want to Upgrade?


To: David R who wrote (8348)12/31/1997 2:02:00 PM
From: Neil Booth  Respond to of 10836
 
The compiler has no way of knowing if pa2 (or pa1 for that matter) will contain a base class or a derived class at runtime.

No, but it doesn't need to. As you say, pa2 (and hence the compiler) doesn't know what type it's really pointing to. But *pa2 (the object pointed to) knows what it is! It has a hidden member pointer to its virtual function table, which is looked up at runtime, as I explained in the other post.

All C++ code can not be resolved at compile time, there is some runtime overhead. That is a fact of which I am quite sure.

True, but the only overhead is what I showed you.

Also, Rod's post about one VFT being a subset of the other was a crucial point that I forgot to mention: the VFT for the derived class is in the same order as the VFT for the base class, possibly with newly-introduced virtual functions tagged on the end. The area of overlap will point to different functions if they're overridden in the derived. But, crucially, because they are in the same order, the compiler knows that any given function call (e.g. your foo) is a fixed offset from the base of the VFT of each class (in your example, the 0th position), whether the VFT is actually that of the base or the derived class. Hence the code "call [CX + 0]" works for both base and derived classes. I hope I'm getting the message across, it's a bit tricky to explain without a pen and paper.

If the penny still hasn't dropped, post exactly the thought processes you're going through.

Cheers!

Neil.



To: David R who wrote (8348)1/1/1998 1:12:00 PM
From: Kashish King  Read Replies (1) | Respond to of 10836
 
David, the compiler doesn't have to know whether a pointer points to a base class or a derived class. Since we're talking about efficiency here, remember that the compiler can often substitute a direct call for a virtual call but that's an optimization issue which we can leave out for now.

class A { virtual void foo( ) ; virtual void bar ( ) ; } ;
class B { virtual void foo( ) ; virtual void zot ( ) ; } ;


When we instantiate an A and a B we get two distinct vtbls, barring optimization as already stipulated. Here's what the vtbls might look like for an object of type A and B respectively, this demonstrates the crucial point:

vtbl for object of type A:
A::foo
A:bar

vtbl for object of type B:
B::foo
A::bar
B::zot


Now, a pointer has to point to an actual instance of an object and that object has to be constructed. There are no vitual constructors, the compiler always knows the exact type of the object being constructed on a given line of code. Since each object gets it's own vtbl it doesn't matter how many pointers there are or what the exact type of the pointer is. If you are pointing to an object type B you will always call B::foo, A::bar and B::zot!

Here's an example using a reference instead of a pointer because you rarely need to use pointers in C++ and you don't have them in Java anyway. Not only does it make the syntax cleaner, it make the code more reliable without doing any null pointer checks and having to decide how to handle that:

Thud ( A & Geek )
{
Geek.foo ( );
}

B Bazola;
Thud( Bazola);
Bazola.zot ( );