Archived

This topic is now archived and is closed to further replies.

Geronimo2000

C++ gotchas: pure virtual function calls

Recommended Posts

This is an extremely specific question I suppose. If anyone owns the Dewhurst book, C++ gotchas, I found my confusion on page 220 in the polymorphism chapter. The end of the chapter appeared to say that calling a pure virtual function (i.e. the version of the function with = 0 ?) within the scope of it''s abstract base class without making the call static (i.e. without the Class:: ??) was undefined! I kept reading to see how I misread it, but I couldn''t see how I did. Is this still true, or how did I misread the book? Thanks a lot for any thoughts or help. G

Share this post


Link to post
Share on other sites
I don't have that book, but what you describe is not entirely correct. You do need to be careful not to call pure virtual functions (either explicitly or implicitly through other member functions) from base class constructors and destructors.

[edited by - spock on July 27, 2003 12:06:11 AM]

Share this post


Link to post
Share on other sites
Ah yes, that was the exact context of the example, and I guess it was implied (?) that this rule was only for constructors and destructors, but I thought why???

1. What''s so special about the constructors and destructors of an abstract base class?

2. Why doesn''t the rule apply to non pure-virtual functions as well?

It just seems like this is so arbitrary...

If the answer is "just because", allright, but if you or anyone else happens to know the real reasons, I''d really like to know.

Thanks a lot for your post.

G

Share this post


Link to post
Share on other sites
If I had to place a bet I would say it has something to do with the assembly translation of virtual functions. I''m not sure how they work at the asm level exactly, but I would put a bet on it.

Share this post


Link to post
Share on other sites
The problem with calling virtual functions from base class constructors and destructors is that you're not dealing with fully constructed objects - the virtual dispatch won't work properly until the entire object is constructed. You can still call a function non-virtually using explicit qualification.

[edited by - spock on July 27, 2003 12:26:11 AM]

Share this post


Link to post
Share on other sites
quote:

1. What's so special about the constructors and destructors of an abstract base class?


As spock said, the objects are only partially constructed. More specifically, the vtable entries have only been filled in for the virtual functions defined by the current constructor and the constructors for those classes it derives from (these are the compiler generated potions of the constructors, not code that you write). Any vtable (a table of the addresses of virtual functions) entry might be changed later by the constructor of a class that derives from the current, so calling any of the virtual functions may call either an empty vtable entry (in the case of pure virtual functions) or the wrong virtual function (in the case of non-pure).

quote:

2. Why doesn't the rule apply to non pure-virtual functions as well?


In my opinion it should, but consider this...

class A
{
A() { std::cout << Func(); }
virtual int Func() { return 1; }
};
class B : A
{
virtual int Func() { return 2; }
}

This would actually output 1 (not 2, as you might be expecting). If there are situations when this is the behaviour you want, then by all means call the virtual from the constructor. But if you want the output to be 2, don't.


[edited by - joanusdmentia on July 28, 2003 2:59:10 AM]

Share this post


Link to post
Share on other sites
Exactly - I believe that ''undefined'' rule should be applied to both pure virtuals and non pure virtuals alike. If not, then apply the other rule... The book says for non pure virtuals, the function is bound to the base class since the derived object isn''t built yet...

If that''s the procedure for a non pure virtual, I don''t see why it couldn''t be applied to a pure virtual (just bind it to the base class).

That was pretty much what my confusion boiled down to. I just thought there was no reason pure virtuals and non pure virtuals couldn''t be dealt with in a consistent manner.


Thanks for all your input.

G

Share this post


Link to post
Share on other sites
quote:
Original post by Geronimo2000
If that''s the procedure for a non pure virtual, I don''t see why it couldn''t be applied to a pure virtual (just bind it to the base class).



Well, if it gets bound to a pure virtual function--you''ve got an error, because that function doesn''t really exist. At best, it''d be a compile error; at worst, it''d make your program crash and die a horrible, painful death. It''s like dereferencing a null pointer. It''d be a Bad Thing (tm). So, most (all?) compilers won''t even let you do it in the first place (as Zipster pointed out).

-Odd the Hermit

Share this post


Link to post
Share on other sites
quote:
Original post by Odd the Hermit
Well, if it gets bound to a pure virtual function--you''ve got an error, because that function doesn''t really exist .

Interestingly enough, pure-virtual functions CAN be defined. Check the standard for more details.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites