Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!tdatirv!sarima From: sarima@tdatirv.UUCP (Stanley Friesen) Newsgroups: comp.lang.c++ Subject: Re: Virtual things, lists, collections, ... Message-ID: <38@tdatirv.UUCP> Date: 14 Jun 91 17:58:45 GMT References: <2885836642@ARTEMIS.cam.nist.gov> Reply-To: sarima@tdatirv.UUCP (Stanley Friesen) Organization: Teradata Corp., Irvine Lines: 50 In article <2885836642@ARTEMIS.cam.nist.gov> miller@FS1.cam.nist.gov (Bruce R. Miller) writes: >Just how is it that Virtual functions work? ie. Where's the type info >at run type stored. Do the objects have (hidden) headers? This is implementation dependent. Any mechanism that provides the required semantics is acceptible. (In real life it must also provide reasonable performance). Thus *any* dependence on the implementation of virtual functions is intrinsicly unportable. >As I understand it the code for SCAN is not replicated (there's only >one version in the object code). Not necessarily, the best compilers do indeed accomplish this in most cases, but it is not guarenteed. (Though it is guarenteed that you will never get any multiple definition errors from linking code using virtual functions). > So somehow that code (or some dispatch >code for VIRT) figures out what the arg is and dispatches. How? I can >think of two ways offhand; 1) every class instance has a header with its type >encoded -- which might be nice to know if you are worried about >tradeoffs of space -- and that might only be needed if the class (or its >children?) define virtuals (can the compiler tell?). 2) whenever a >virtual (or caller of virtual! or caller of....) is called an extra type >code is pushed on the stack (again, can the compiler tell?). >Is either of these the `right' way? or both? (so long as it works, it >doesn't matter...) I think either would be a legal implementation. But I do not know of any existing compiler that uses either one. Most existing compilers implement virtual functions by adding an extra hidden data member to the class record layout. This member is a pointer to a table of function pointers, with one entry per virtual function. [This table is traditionally called the vtable]. The constructor for each class (including each derived class) is augmented with code to initialize this pointer to the proper value for the actual class of the object. This is possible because you must know the exact type of an object to construct it, so the constructor "knows" the type exactly. A call to a virtual function is then simply indirected through the vtable. In pseudo-C this is essentially (*virt_object.__vtbl_ptr__[FUNC_ID])(args). Now, remember - DO NOT RELY ON THIS IMPLEMENTATION - it is NOT guarenteed. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)