C++ Template interface (list implementation)


Keywords:c++ 


Question: 

I am trying to implement a list data structure in C++.

I want to define a list interface which would be later inherited by implementation such as ArrayList or LinkedList.

I'd like to be able to use it like

List<int>* testList = new LinkedList<int>;

So i've tried to implement full virtual templated class but then realized i cannot mix virtual and templated methods. I tried much different ways and im encountering problems all the way.

Whats the best way to do it ?

Edit (problematic code). I'm trying to make interface to look like this:

template<typename T>
class List {
public:
    virtual void add(T*) {};
    virtual void remove(unsigned int) = 0;
    virtual unsigned int size() = 0;
    virtual void get(unsigned int) = 0;

    virtual ~List();
};

and then im trying to implement it here:

template<typename T>
class LinkedList : public List<T> {
/* some stuff */
public:
    LinkedList();

    virtual unsigned int size();
    virtual void add(T*); // the problem i guess
    virtual void remove(unsigned int);
    virtual void get(unsigned int);

    virtual ~LinkedList();
 };

1 Answer: 

So i've tried to implement full virtual templated class but then realized i cannot mix virtual and templated methods.

Your example code indicates, that you don't want virtual, templated methods, but a template class that has virtual methods. The former is not allowed, the latter IS (this is a common point of confusion).

So this is perfectly valid code:

#include <iostream>
#include <memory>

template<class T>
class List{
public:
    virtual void push()=0;   
    virtual void pop()=0;
    virtual ~List()=default;
};

template<class T>
class LinkedList: public List<T>{
public:
    virtual void push() {
        std::cout << "Pushed element to Linked List"<< std::endl;
    }
    virtual void pop() {
        std::cout << "Poped element from Linked List"<< std::endl;
    }
};

template<class T>
class ArrayList: public List<T>{
public:
    virtual void push() {
        std::cout << "Pushed element to ArrayList"<< std::endl;
    }
    virtual void pop() {
        std::cout << "Poped element from ArrayList"<< std::endl;
    }
};

int main()
{

    List<int>* list1=new LinkedList<int>();
    List<int>* list2=new ArrayList<int>();
    // And this is how you would actually create objects on the heap nower days:
    std::unique_ptr<List<int>> list3=std::make_unique<LinkedList<int>>();

    list1->push();
    list2->push();
    list3->push();

    list1->pop();
    list2->pop();
    list3->pop();

    delete(list1);
    delete(list2);
    //no delete(list3) needed
    return 0;
}

Besides that, I don't know, why you want to do that. C++ has a perfectly fine implementation of a linked list and an implementation of and array/vector and thanks to iterator based semantic, you can run (almost) any algorithm on them without the need for a common base class.

I apologize, if this sounds harsh, but it looks like you are comming from Java and trying to learn C++. But instead of learning C++, you try to write wrappers, that make C++ look like java. While this is certainly possible most of the time (as long as you don't forget, that standard c++ doesn't have a garbage collector) its often not a sensible approach. whether that holds true in your case of course depends on your application. But my recommendation ist to learn about iterators and the standard library algorithms.