views:

124

answers:

3

Hi, can I mix inheritance and templates this way ? :

template <class T> 
class AbstractType { // abstract
//....
}

template <class T> 
class Type1 : public AbstractType<T> {
//....
}

And later on, can I use these classes like this:

AbstractType<SomeClass>* var1 = new Type1<SomeClass>();

Thx for help.

+7  A: 

Yes, you can. You can use the template parameter for whatever you want, passing into the base templated class included.

sharptooth
Cool :) I'm wondering why there is no anstractlist in stl ? It seems to be doable and one could use different implementations of lists.
Seba
@Seba - <list> already allows for use of custom allocator. What other implementation details would you wish to alter?
Steve Townsend
@Steve - There are many ways to implement lists. So I thought that i could declare for example a function parameter as abstract type and let the user decide what implementantion he/she wishes to use. I'm just wondering :)
Seba
@Seba: I don't see any compelling case to have a base class. The container is usually elected because of precise requirements on the performance / interface and the STL offer the most efficient implementations for the requirements stated. The STL has been crafted with an entire different mindset than OO (and for the better).
Matthieu M.
@Seba: Matthieu M. is right. Doing it the interface way is doing it the OO-way. The STL is template based. As long as you respect the STL interface for a list, you can replace one list by another without needing to have base classes and virtual methods between them. Like Leonidas declared once: `this is templates!`... ^_^ ...
paercebal
@paercebal: So in order to achieve better performance STL designers decided to use approach that didn't require using virtual methods ?
Seba
@Seba: Not exactly (even if this is a side effect). The real point of generic programming is to avoid unnecessary base classes. OOP is all about base classes, and common overridden methods. C++ is multiparadigm, and in the current case, generic programming (having a similar interface) does it better and with less coupling than OOP (a common base class). The word "similar" is very important here: I did not write "exactly the same interface". This is not an error.
paercebal
+1  A: 

You can use any type with the class template, provided the type is compatible with the class definition

e.g.

template<class T> struct S{
   T mt;
};

Such a struct can be instantiated for T = int, T = double, but not T = void.

Chubsdad
+3  A: 

You can, but it's not going to be as useful as you may think. You can define the structures like this:

#include <string>
#include <vector>
using namespace std;

template<typename Val>
class Base
{
public:
    virtual Val DoIt() const = 0;
};

template<typename Val>
class Derived : public Base<Val>
{
public:
    Derived(const Val& val) : val_(val) {};
    Val DoIt() const { return val_; }
protected:
    Val val_;
};

int main()
{
    Derived<string> sd("my string");
    string sd_val = sd.DoIt();

    Derived<float> fd(42.0f);
    float fd_val = fd.DoIt();
}

But when you're defining abstract base types, you're often going to want a collection of them, and to be able to call through a base class pointer to get polymorphic behavior. If you templatize the base class, you're not going to be able to do this because each variation of the template parameters will create a different type. Base<int> is completely different than Base<string>, and you can't just get a Base* that points to either one.

This code will not compile:

vector<Base*> my_objs;
John Dibling
Undertood. Thx.
Seba