Message-Id: Comments: Authenticated sender is From: "Salvador Eduardo Tropea (SET)" Organization: INTI To: rwhite AT bellatlantic DOT net, djgpp AT delorie DOT com Date: Mon, 28 Jul 1997 17:42:06 +0000 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: Undefined reference to virtual table Precedence: bulk Robert C White Jr wrote: > Thomas Happ XIII wrote: > > > > This is an oop c++ problem . . . > > I have a class, Map, and a subclass, PicMap. My Map class has no > > constructor, three virtual methods, and three non-virtual methods. My > > PicMap class has a constructor with several arguments, a destructor, > > overrides of the three virtual methods in Map, and some of its own > > methods. It compiles fine, but when I go to link, it says, ". . . in > > function Map::Map(void) . . . undefined reference to 'Map virtual table'". > > First of all, I didn't make a function Map::Map() (or even a function > > PicMap::PicMap()), but after the error I tried doing the former and it > > still said the same thing. It was my understanding that the virtual > > method table of a subclass is identical to that of the parent class but > > with its own methods concatenated on the end, so where is this error > > coming from? > > Tom > > You haven't *quite* provided enough information. The things most > notably are A) does Map have any ancestor classes? and B) does Map use > any data types with constructors? C) what compiler are you using? > > My "generic" advice is: > > 1: any class you intend to inherit from and use polymorphically (e.g. > referencing a PicMap from a Map pointer) where any of the child classes > will have a destructor, should have *virtual* destructors at the roots > of the class trees even if that destructor is empty. This ensures the > correct destructor is always available to the system. I sugest it too. > 2: make sure that you re linking in definitions for all the non-pure > virtual functions in all the ancestor classes. The "need not be defined > if never used" rule does not apply, occuring in any virtual table for > any type constitutes use (e.g. it needs to be resolved by the linker). > Most link-time errors involving the virtual tables involves not having a > definition for a virtual function linked in (usually optimized out by > hand because of "I never call that" thoughts by the author) That's a very common problem. In addition I'll say that: Ever provide at least a dummy body like this: virtual int member(void) {}; Most of the time gcc brings this silly error (undefined reference to 'Map virtual table') just because some of the functions don't have a declaration. And most of the time you don't want to declare the body because they are prototypes. > 3: check for any compile-time options that affect the placement of > virtual tables. If you are doing multi-file builds whit these options > inconsistently set all sorts of things may go wrong. Is strange that somebody makes that. > 4: if you are doing multi-file "make"s, check that all your dependencies > are correct. One old module can really botch things badly. One very important thing with GCC is that classes with virtual members must be declared on headers and at least one member must be in a .cc file. Sometimes if you put a base class and a derived class both declared in the same .cc file but not in a header gcc will go crazy telling he can't find some members that in fact are there. Additionally in extreme cases you'll need to use #pragma implementation and #pragma interface to get the right error.For example in the case 2 the reported error isn't so useful but forcing all with the pragmas you'll know what member is the one with no declared body. SET ------------------------------------ 0 -------------------------------- Visit my home page: http://www.geocities.com/SiliconValley/Vista/6552/ Salvador Eduardo Tropea (SET). (Electronics Engineer) Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA TE: +(541) 759 0013