是否可以从模板基类继承而不是使派生类成为模板?

时间:2016-02-17 12:22:56

标签: c++ templates inheritance

我尝试从模板基类继承但是我得到了几个错误,因为我的派生类不是模板类。我也不想要它,我只是想分享一些变量,让派生类实现它们。

//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*>();
}

所以我就是想要从基类实现此Qlist,但具有特定的类型参数,如MyType。 在c ++之前,我还没有使用模板与继承相结合,我尝试了几件事,但是他们没有成功。

修改 所以,我尝试像下面解释的dtbeaver,但后来我收到以下错误消息: 未定义引用&#39; Base :: Base()&#39;。 我得到了构造函数和解构函数

2 个答案:

答案 0 :(得分:6)

,这完全可能,但您可能希望保留基本类型的别名。

实施例

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;
};

其次,在模板实例化期间,所有定义必须对编译器可见。您无法为模板提供常规单独的标头和实施文件,您可以使用一些额外的技术。请参阅Why can templates only be implemented in the header file

答案 1 :(得分:2)

模板类声明和实现可以在分隔的文件中拆分,但您必须在使用模板的位置包含这两个文件。

您的基本模板实现中存在语法错误:

//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*>();
}

并且不要忘记使用#pragma once或guard definitions