Sorry if the title is not clear.But, I'll try to explain the problem clearly.
I am working on a c++ and QT using MVC for the application architecture:
- Some description for application structure:
Model Section (designed using polymorphism pattern):
is responsible for database related stuff, It has an IDataBase.h interface and its implementation for sqlite database type.
IDataBase.h :namespace model{ class IDataBase; } class IDataBase { public: virtual ~IDataBase(){ //; } virtual bool connect(const QString &db) = 0; virtual bool insertData(QMap<QString,QVariant> &queryData, const QString &table) = 0; };
sqlitedb.h
class SqliteDB: public IDataBase { public: SqliteDB(); ~SqliteDB(); bool connect(const QString &db) bool insertData(QMap<QString,QVariant> &queryData, const QString &table); private: QSqlDatabase m_database; };
Controller Section: I am using the template class DataBaseService to manage any type of databases (mysql, sqlite ....).
DataBaseService.h // template variable is the database type class
template<class T> class DatabaseService { public: DatabaseService(); ~DatabaseService(); bool addProduct(QMap<QString,QVariant> &queryData, const QString &table); private: std::unique_ptr<IDataBase> m_database; };
DataBaseService.cpp
template<class T> DatabaseService<T>::DatabaseService() { m_database = std::make_unique<T>(); m_database->connect("db.sqlite"); }
- The Problem is :
When I try to create a pointer of class DatabaseService with the template variable SqliteDB in main.cpp file :
DatabaseService<model::SqliteDB> *sqliteDb = new DatabaseService<model::SqliteDB>();
I get This unresolved externals error :
error: LNK2019: unresolved external symbol "public: __cdecl DatabaseService::DatabaseService(void)" (??0?$DatabaseService@VSqliteDB@model@@@@QEAA@XZ) referenced in function main
- My Questions :
- what is wrong in my design?
- Is there any better way to design the database workflow?
- Edit:
After I Read the links that are provided by Miles Budnek I understood how templates actually works and I know that I have three options to write template class implementation :
Write implementation directly in header file.
write implementation in .cpp file an write explicit instantiations in cpp file.
- Write implementation in .tpp file and include it at the end of header file.
So, I used the second method and wrote explicit instantiation for using model::SqliteDB class: at the end of DataBaseService.cpp
template class DatabaseService<model::SqliteDB>;
This solved the unresolved externals error! But now I have another error when trying to create an IDatabase pointer for SQliteDB object in DataBaseService.cpp in the line:
m_database = std::make_unique<T>();
Errors :
error: no viable overloaded '='
error: C2679: binary '=': no operator found which takes a right-hand operand of type 'std::unique_ptr>' (or there is no acceptable conversion) with [ T=model::SqliteDB, _Ty=model::SqliteDB ]