简体   繁体   中英

C++ Template Container Inheritance

I'm somewhat new to C++ after having spent too much time in the Java wilderness.

Suppose I have data classes A and B and a container class, which I'll call Container:

class A
{
public:
  virtual void foo()
  {
    cout << "I am an A" << endl;
  }
};

class B : public A
{
public:
  void foo()
  {
    cout << "I am a B" << endl;
  }
};

template <class T> class Container
{
public:
  T *_t;

  Container(T *t)
  {
    _t = t;
  }
};

The Java equivalent for what I would like to would look something like

B b = new B();
Container<? extends A> aContainer = new Container<B>(b);

How should this be done in C++? Is this even canonical?

The following code gives a compilation error:

B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);

So far, Google has been unhelpful in finding an equivalent for "? extends".

== Edit ==

The solution was to rewrite my code so that a "? extends" would not be needed, as Isaac Drachman describes below.

If you are using C++11(or boost probably) you can use std::is_base_of<A,B> which contains (value=) true if A is a base class of B.

Anyway, you can do this:

template<class T>
class container {
    void append(T* what);
}

consider container<base> if you try and do append(derived) it's fine because a pointer to a derived can be cast to a pointer of base.

However this lets you have a list of anything.

If you want to control it, like "extends" in Java;

static_assert(!std::is_base_of<base,T>::value,"You must derive from base");

Stick that somewhere and get a nice error message of "you must derive from base"

With templates there's no way to specify "T extends B" because the template system is complex and more advanced (able to do more), so if you specify a type with the same method names it could by change work, or you can get horrible errors if you miss a method name that don't seem to be telling you you missed a method name.

Your declarations of the A, B, and Container classes are valid and will work for this purpose. The syntax in the following is causing an error.

B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);

First off, when using the constructor for a class with a new , you need to use the class name (like in Java), not the object's. As for the inheritance aspect, your container is declared as Container<A> and therefore cannot be constructed as a Container<B> , even though B inherits from A. Using Container<A> type and constructor for your aContainer object will allow you to contain either an A object or B object, which is what I think you're trying to do. Your code should therefore be the following:

B *b = new B();
Container<A> *aContainer = new Container<A>(b);

That compiles and should work for you. Feel free to explain if that doesn't fit what you want to do. Hope it helps, though!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM