teodron
teodron

Reputation: 1438

Polymorphic templated classes with polymorphic template parameters

In a simplistic design, a class B inherits a class A polymorphically. A templated class, Base<T> has a T* member that is used for further operations. A Derived<T> inherits from Base<T> polymorphically. What would be the syntax that allows this kind of object creation:

Base<A>* a = new Derived<B>();

For further reference, the code I used looks like this (of course, the conversion does not succeed):

class A
{
public:
  A()
  {
    cout<< " A  ";
  }
  virtual void one()
  {
    cout<<" 1 ";
  }

};

class B: public A
{
public:
  B()
  {
    cout << " B  ";
  }
  void one()

  {
      cout << " 2 ";
  }
};

template <class T>
class Base
{

public:
    T* thing;
  Base()
  {
    cout<<"Base";
    thing = new T;
  }
  template <class S>
  Base(Base<S>* obj)
  {
    thing = obj->thing;
  }
  virtual void poly(){ thing->one();}
};
template <class T>
class Derived : public Base<T>
{
public:
  Derived()
  {
    cout << "DERIVED ";
  }
  virtual void poly(){ 
};
int main(int argc, char** argv)
{
  //Base<A>* a = (new Derived<B>());
  return 0;
}

Virtual destructors and proper memory management omitted on purpose for code brevity.

EDIT : the sole purpose of this construction would be to keep, say, a list of BaseTemplated<BasePolymorphic>* pointers together, and not use BaseTemplated<Derived1> to BaseTemplated<DerivedN> for all N subclasses of a base, polymorphic class.

Upvotes: 2

Views: 2059

Answers (3)

Paul Michalik
Paul Michalik

Reputation: 4381

This can't work for pointers. The result of new Derived<B> cannot be assigned to Base<A>*, in fact it can't be even assigned to Derived<A>* since all those types are unrelated. Do you really need this relationship between the templated wrappers? Wouldn't it suffice to guarantee the convertibility of the values of Base<B> and Base<A> (as the standard smart pointers do)? You already have this with the templated conversion constructor...

//...
Base<B> tB(new B);
Base<A> tA = tB;
//...

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66194

First, tell me when we get to the "simplistic" part.

Peel back all half of the templates to just concentrate on the part you're trying to polymorph). Eventually you have distinct classes Base<A> and Base<B>. (the latter through derivation of Derived<B>).

Neither of these inherit from their respective template parameters. Therefore the relationship (hierarchical or otherwise) of A to B is irrelevant. Base<A> and Base<B> are distinct and unrelated, and therefore what you're trying to do as-writen cannot work. In fact, even if the did inherit from a A and B respectively, the very best you could hope for is an A* pointer, which you aren't using in your sample.

And I'll gladly delete this if shown otherwise, because I'm genuinely curious.

Upvotes: 4

n. m. could be an AI
n. m. could be an AI

Reputation: 119847

A bag of apple Base<B> is not a bag of fruit Base<A> because you can put a peach, a cherry, and a pear in a bag of fruit.

Upvotes: 3

Related Questions