Sign in to follow this  
code4fun

Templates.. Inheritance..

Recommended Posts

code4fun    258
Alright, I think I've gotten over my head, so if there are some blantant misunderstandings here on my part, I'm more than willing to accept that maybe I've gone too far beyond my capabilities. I've looked through a lot of previous topics on the subject here on the forums, but I can't seem to get them to work with my situation. I should probably be looking more into boost or similar, but I'm not really sure, so here it goes.. I created a nice little templated class, and then wanted to put my templated classes into an std::vector. Since the templates are different, this doesn't work. No problem, I created a base class and made a vector of those instead. Now comes the problem (reduced code for simplicity, or so I hope):
#include <iostream>
#include <vector>

class cBase
{
public:
  virtual void doSomething(){}
};

//not actually using the template for anything in this example
//but you get the idea I hope...
template <class T>
class cDerived : public cBase
{
public:
  void doSomething(){std::cout << "yay...\n";}//never gets called
};

int main()
{
  std::vector<cBase> baseList;

  cDerived<int> derived, d2, d3; //etc..
  baseList.push_back(derived);
  baseList.push_back(d2);
  baseList.push_back(d3);

  std::vector<cBase>::iterator i;
  for(i = baseList.begin(); i != baseList.end(); ++i)
  {
     //calls cBase::doSomething() which makes sense, but what I 
     //want is cDerived::doSomething()...
     i->doSomething();
  }
  
  return 0;
}

Now, I think I understand why only the cBase::doSomething() function is being called.. so my question is either how do I get around it, or should I rethink my design entirely? :P Previous posts seemed to suggest operator overloading / copy constructor methods.. but I didn't really follow. Any help would be wonderful, thanks! -code4fun

Share this post


Link to post
Share on other sites
SiCrane    11839
Don't store polymorphic types by value in a container by value. You should store (smart) pointers to the objects instead. Otherwise you run into problems with slicing: when only the base part of a derived object is copied.

e.g.: std::vector<cBase *> baseList instead of std::vector<cBase> baseList

Share this post


Link to post
Share on other sites
Enigma    1410
Quote:
Original post by code4fun
...

I created a nice little templated class, and then wanted to put my templated classes into an std::vector. Since the templates are different, this doesn't work...


Do mean that you were trying to do this:
std::vector<SomeClass<int>>
?
If so, all you need to do is insert a space between the angle brackets:
std::vector<SomeClass<int> >

This is because of the way C++ code is tokenised. '>>' is always interpreted as the single shift-right token whereas for templates it needs to be recognised as two greater-than tokens.

Enigma

Share this post


Link to post
Share on other sites
code4fun    258
Thanks for the tip Enigma, but what I was trying to do was more like this:

A<int> a;
B<float> b;

myVector.push_back(a);
myVector.push_back(b);

(I only used type <int> in the OP because I was trying to reduce my code to be as basic as I could get it.)

Which doesn't work, so I gave A and B a base class and constructed my vector from that. Thanks though :) .. and using pointers fixed the problem, silly me, thanks SiCrane!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this