Problem executing methods of a generic class

0

I'm developing a generic DAO class in Qt, but when I compile I have the following error, when I call any method from my DAO object:

Debug\debug\main.o:-1: In function Z5qMainiPPc':

undefined reference to bool DAO::add<Product>(Product*)'

collect2.exe:-1: error: error: ld returned 1 exit status

The error occurs here dao.add(produto); or here dao.remove(produto);

I would like to know what I may be doing wrong.

Main

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));    

    //Teste

    Product *produto = new Product();

    DAO dao;

    produto->setCode("123456");
    produto->setName("Teste");
    produto->setPrice(10.33);
    produto->setUnityMeasure("KG");

    dao.add(produto);
    //dao.remove(produto);

    //Fim Teste

    return app.exec();
}

Headers

#ifndef DAO_H
#define DAO_H

#include <QObject>

class DAO:public QObject
{
    Q_OBJECT
public:
    DAO();
    template<typename T> bool change(T *entity);
    template<typename T> bool remove(T *entity);
    template<typename T> bool add(T *entity);
    template<typename T> T *find(T *entity);
    template<typename T> QList<T *> *findAll();
};

#endif // DAO_H

Implementation

#include "dao.h"

DAO::DAO()
{

}

template<typename T>
bool DAO::change(T *entity)
{
    return false;
}

template<typename T>
bool DAO::remove(T *entity)
{
    return false;
}

template<typename T>
bool DAO::add(T *entity)
{
    return false;
}

template<typename T>
T *DAO::find(T *entity)
{
    return NULL;
}

template<typename T>
QList<T *> *DAO::findAll()
{
    return NULL;
}
    
asked by anonymous 04.04.2017 / 20:03

1 answer

0

I think the error is in the implementation. The right thing would be like this:

template <typename T>
T* DAO<T>::find(T* entity)
{
    return nullptr;
}

And as far as I know, template classes need only be in the header, or the linker will issue errors. And would not it be better to declare the whole class as a template soon?

#ifndef DAO_H
#define DAO_H

#include <QObject>

template <typename T>
class DAO  : public QObject
{
    Q_OBJECT

public:
    DAO();
    bool change(T *entity);
    ...
    ...
};

template <typename T>
DAO<T>::DAO()
{

}

template <typename T>
bool DAO<T>::change(T *entity)
{
    return false;
}

...
...
...

#endif // DAO_H

Note: Ah, yes. And when instantiating a generic class, you need to declare the type:

DAO<QString> dao;

If you only merge the method as a template as you did, the compiler can deduce the type you want to pass.

    
06.04.2017 / 08:36