deriving from a templated class

Started by
2 comments, last by ronenkre 12 years, 5 months ago
Hi all, just a minute ago I tried to derive a class from a templated class. However, the compiler won't let me to put the keyword "[color="#FF0000"]virtual" for the templated class's methods. So I don't put the keyword. And then I derive a class from the templated class. However, the derived class's method doesn't seem to get called :(

here it is the ripped source code

//res_mgr.h

template<class T>
class res_mgr
{
public:
res_mgr(){ printf("allocated"); }
virtual ~res_mgr(){ printf("deleted"); }

void add(const std::string& name){ printf("added %s\n", name.c_str()); }
};

//font_mgr.h
class font_mgr : public res_mgr<font> //font is ok, no need to check its implementation
{
public:
font_mgr()
:res_mgr<font>()
{
}
~font_mgr()
{
}

void add(const std::string& name){ printf("font added [%s]\n", name.c_str()); } //this function never gets called!! I wonder why :(
};


for example, I create a font_mgr

font_mgr *mgr = new font_mgr;

when I call
mgr->add("blah blah");

the function that gets called is always the res_mgr::add(). I want it to call font_mgr::add() instead. btw I haven't slept for 8 hours now and I'm confused. Puh lease help this poor fellow :(
the hardest part is the beginning...
Advertisement

for example, I create a font_mgr

font_mgr *mgr = new font_mgr;

when I call
mgr->add("blah blah");

the function that gets called is always the res_mgr::add().
It definitely shouldn't be, as you can see you've a pointer to a [font="Courier New"]font_mgr[/font] instance so it should definitely that method that gets called.


If you changed your initialisation line to:

res_mgr<font> * mgr = new font_mgr;

Then calling [font="Courier New"]add()[/font] would have the effect of calling the [font="Courier New"]res_mgr<>[/font] version of [font="Courier New"]add()[/font] because it isn't virtual. Making it virtual would resolve that.

It all should work, perhaps posting the errors would help us diagnose.
duh sorry I've been cheating and not giving you the full picture. actually the add method isn't called directly, but it's called by res_mgr::get() method

I'll show you the full source code

//res_mgr.h
#ifndef _RES_MGR
#define _RES_MGR

#include <string>

template<class T>
class res_mgr
{
public:
res_mgr(){printf("created res_mgr\n");}
virtual ~res_mgr(){printf("deleted res_mgr\n");}

void add(const std::string& name){ printf("added res %s\n", name.c_str()); }
void get(const std::string& name){ add(name); }
};

#endif

//font.h
#ifndef _FONT
#define _FONT

#include "res_mgr.h"

class font
{
public:
font(){ dummy = 0; }

int dummy;
};

class font_mgr : public res_mgr<font>
{
public:
font_mgr();
~font_mgr();

void add(const std::string& name);
};

#endif

//font.cpp
#include "font.h"

font_mgr::font_mgr():res_mgr<font>(){ printf("font mgr created\n"); }
font_mgr::~font_mgr(){ printf("font mgr deleted\n"); }

void font_mgr::add(const std::string& name)
{
printf("font added %s\n", name.c_str());
}

//main.cpp
#include "font.h"

int main(int argc, char** argv)
{
font_mgr* mgr1 = new font_mgr;

mgr1->get("test.fnt");

delete mgr1;

return 0;
}


it compiled just fine, but still, the get() method call res_mgr::add(), not the font_mgr::add(), here's the output

created res_mgr
font mgr created
added res test.fnt
font mgr deleted
deleted res_mgr
the hardest part is the beginning...
EDIT : I fixed it! I rebuild a new project and included the files again, and somehow it worked well...hmm mysterious...:cool:
the hardest part is the beginning...
I would still read carfully what dmatter wrote you. he is right.

Even though the code you are using now will work. In the future if you decide to change the pointer to
res_mgr[color="#008800"]<font> it will stop working.

Either add virtual to your template class, or change the function "add" to "add_something" in the derived class. otherwise it is bad practice.

This topic is closed to new replies.

Advertisement