3

I tried to inherit from a template base class but I get several errors because my derived class is no template class. I also don't want it to be, I just want to share some variables and let the derived class implement them.

//base.h
template <typename T>
class Base
{

public:
     explicit Base(QWidget *parent);
    ~Base();

protected:
    QList<T*>* list;
    T* selectedObject;

};

//base.cpp
#include "base.h"

template <typename T>
Base<T>::Base(QWidget* parent)
{

}

template <typename T>
Base<T>::~Base()
{

}


//derived.h
namespace Ui
{
    class Derived;
}

class Derived: public QWidget, public Base<MyType>
{
    Q_OBJECT

public:
    explicit Derived(QWidget *parent = 0);
    ~Derived();

private:
    Ui::Derived*ui;
};

//derived.cpp
Derived::Dervied(QWidget* parent) : QWidget(parent), Base<Mytype>(parent)
{
    list = new QList<MyType*>();
}

So I e.g. want to implement this Qlist from the base class but with a specific type parameter like MyType. I haven't worked with templates in combination with inheritance before in c++ and I tried several things but they didn't work out.

EDIT So, I tried like dtbeaver explained below but then I get following error message: undefined reference to 'Base::Base()'. I get this for the constructor and deconstructor

Greenfish
  • 358
  • 2
  • 5
  • 19
  • 2
    Yes it's possible. What didn't work for you specifically? – πάντα ῥεῖ Feb 17 '16 at 12:25
  • It's possible, and I am making _extreme_ use of it in my current project (which thankfully uses gtkmm rather than Qt - controversial.) You say it doesn't work, but _how_? Is there an error reported? What is it? "I tried several things but they didn't work out." **In what way**? – underscore_d Feb 17 '16 at 12:40
  • `Base` doesn't have default constructor in your case. Unrelated to the fact it is template btw. – Jarod42 Feb 17 '16 at 12:40
  • 1
    `base.cpp` is suspicious too. – Jarod42 Feb 17 '16 at 12:42
  • base.cpp constructor is filled in my original example but i didn't want to put this is in as it does not matter for my question. The errors I got were endlessly going on with every correction i made so i didn't want to post them. I just wanted someone to tell me the basic principle of how to do this and that's why I made a big abstraction of my real example and provided in a way for others to understand what i want to do. The right answer is down below, it is because i am separating header and implementation – Greenfish Feb 17 '16 at 12:53
  • You forget rename of base.cpp to base.hpp and #include "base.hpp" to derived.cpp – user2807083 Feb 19 '16 at 14:00
  • did this...still get this error message – Greenfish Feb 20 '16 at 20:41

2 Answers2

9

Yes, it's totally possible but you may want to keep an alias of the base type.

Example

class Derived: public QWidget, public Base<MyType>
{
    Q_OBJECT

public:
    using BaseType = Base<Mytype>;  //alias, will be useful someday
    explicit Derived(QWidget *parent = 0);
    ~Derived();

private:
    Ui::Derived*ui;
};

Secondly, during template instatiation, all definitions must be visible to the compiler. You can't really have the regular separate header and implementation files for templates, You can with a few extra techniques. Please see Why can templates only be implemented in the header file

Community
  • 1
  • 1
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
3

Template classes declaration and implementation can be splitted in separated files, but you must include both in place where you using template.

And you have syntax errors in your base template implementation:

//base.h
template <typename T>
class Base
{

public:
     explicit Base(QWidget *parent);
    ~Base();

protected:
    QList<T*>* list;
    T* selectedObject;

};

//base.hpp
#include "base.h"

template <typename T>
Base<T>::Base(QWidget* parent)
{

}

template <typename T>
Base<T>::~Base()
{

}


//derived.h
namespace Ui
{
    class Derived;
}

#include "base.h"

class Derived: public QWidget, public Base<MyType>
{
    Q_OBJECT

public:
    explicit Derived(QWidget *parent = 0);
    ~Derived();

private:
    Ui::Derived*ui;
};

//derived.cpp
#include "base.hpp"
Derived::Dervied(QWidget* parent) : QWidget(parent), Base<Mytype>()
{
    list = new QList<MyType*>();
}

and don't forget to use #pragma once or guard definitions

user2807083
  • 2,962
  • 4
  • 29
  • 37