C++ Templates + Inheritence

Started by
3 comments, last by visitor 13 years, 4 months ago
Hi,

As the title mentions, this thread is more about general C++ syntax. In Java it is possible to write the following

public class Vehicle{  //Class Info}public class Car extends Vehicle{  //Class Info}


and then as a generic class

public class VehicleShop<vehicletype extends Vehicle>{  //Class Info}


Now what this says is that the Vehicle Shop can hold any object which is of the type Vehicle or any of its subclasses. Now I've got two questions regarding this concept:

1.
Is it possible to write the above in C++?

2.
If I have an abstract class called Character, with a reference to a template class called StateManager, is it possible to use for example AICharacter as a template argument in one subclass, and Player as a template argument in the other subclass? e.g.

class Character{   StateManager<Character>* stateMgr;     StateManager<Character>* getStateManager();//Clearly this won't work, just to illustrate};class AICharacter : public Character{  StateManager<AICharacter>* getStateManager();};class Player : public Character{  StateManager<Player>* getStateManager();};


Thanks in advance.
Advertisement
Quote:
1. Is it possible to write the above in C++?

Not easily. C++ templates are far more flexible than Java's generics. I'm sure there is a SFINAE method of testing the above.

In most cases C++ programmers will use a form of "duck typing" for templates. That is, if the class provided as a template argument does everything it is required to do at compile time, then it is consider to map to the "concept" the template type requires.

This is a far more powerful and interesting mechanism than Java has. For example, the Standard C++ Library specifies various iterator concepts, and because pointers map those concepts then you can use pointers or aggregate types as iterators. C++0x was going to make the approach more explicit, allowing for concept interfaces and concept maps, but last I heard this was abandoned as being too complex.

2. No. Concrete template types are unrelated. You could have a non-template base class, and then derive subclasses from it. Whether that is a good idea depends on what a StateManager does.
If I understand what you're saying correctly, what you need to do is use pointers to the desired type hierarchy, rather than instances. In C++, templates give you compile-time polymorphism -- you get multiple behaviors, but they are known statically at compile time.

In order to get different runtime behavior, you need virtual dispatch, which you get through pointers.

This is akin to the problem in C++ that you can't create a container (say, std::vector) which contains actual instances of a type and its subtypes. Instead, you create a vector of pointers to the desired base type, deal with the dereference overhead, and must ensure that instances are allocated and deallocated properly.

Of course, Java must be doing something similar to this in the background through its own type system, but it expresses it differently since the language doesn't expose pointers.

throw table_exception("(? ???)? ? ???");

Alright, thanks for your replies :) I'll make notes of this.
As for the first question, you can simply throw in a static assertion (either C++0x, a boost one or home-made) together with the (c++0x / boost) type_trait called is_base_of.

#include <type_traits>class Vehicle {};class Car: public Vehicle {};template <class T>class VehicleShop{    static_assert(std::is_base_of<Car, T>::value, "VehicleShop instantiated for a non-Vehicle");};int main(){    VehicleShop<Car> a;    VehicleShop<int> b;}

This topic is closed to new replies.

Advertisement