Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: C++
Expertise: Beginner
Aug 29, 2000

Derive from STL Map<>

Question:
I created my own map class (called it Mapper) by creating a template class and deriving from STL map container class. I did so because I wanted to have some extra user-defined methods in this class. I don't have any problems compiling if I only use the methods provided by the STL map class. However, when I try to make a call to one of the new methods in Mapper, I get the following linking error:

--------------------Configuration: mapfunc - Win32 Debug--------------------
Compiling...
runmapper.cpp
Linking...
runmapper.obj : error LNK2001: unresolved external symbol 
"public: int __thiscall Mapper::SmartMatch(class
std::basic_stringshort>,class std::allocator > const &)" (?
SmartMatch@?$ Mapper@H@@QAEHABV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z) Debug/mapfunc.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe. mapfunc.exe - 2 error(s), 0 warning(s)

By the way, runmapper.cpp is the driver program and mapfunc is the project name. I have three user-defined methods (one of them is SmartMatch(key)) that when I try to call, from the driver program, give me the same compilation error (linking error).

Answer:
The compiler must see the definition, not just the declaration, of a template in order to instantiate it. It looks like you #included only the declaration (i.e., the prototype) of your added member function:

int Mapper::SmartMatch(std::wstring); //  prototype

The compiler needs to see its definitions (implementation), too. If you're using Visual C++, my advice is to implement template member functions inline, inside the header file that declares the class template.

Note that deriving from STL containers is usually a bad idea because STL containers have no virtual destructors or virtual member functions. This can cause undefined behavior in certain conditions, for example, if you pass a pointer to std::map<> which actually points to a class derived from std::map<> and has its own destructor. In this case, the derived class's destructor isn't called:

// mapper is derived from std::map
std::map < int > * p new mapper < int >; 
delete p; /*undefined behavior; 
only map < int >::~map < int > called*/

If you need to extend STL's functionality, it's better to use containment rather than public inheritance.

DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap