Указатель базового класса, указывающий на объект производного класса, который является переменной шаблона в другом классе
Извините, если название не ясно. Но я постараюсь объяснить проблему ясно.
Я работаю на C++ и QT, используя MVC для архитектуры приложения:
- Некоторые описания для структуры приложения:
Модельный разрез (разработан с использованием паттерна полиморфизма):
отвечает за вещи, связанные с базой данных, имеет интерфейс IDataBase.h и его реализацию для типа базы данных sqlite.
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; };
sqlite db.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; };
Секция контроллера: я использую шаблон класса DataBaseService для управления базами данных любого типа (mysql, sqlite....).
DataBaseService.h// переменная шаблона является классом типа базы данных
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"); }
- Проблема в:
Когда я пытаюсь создать указатель класса DatabaseService с переменной шаблона SqliteDB в файле main.cpp:
DatabaseService<model::SqliteDB> *sqliteDb = new DatabaseService<model::SqliteDB>();
Я получаю эту неразрешенную внешнюю ошибку:
ошибка: LNK2019: неразрешенный внешний символ "public: __cdecl DatabaseService::DatabaseService(void)" (??0?$DatabaseService@VSqliteDB@model@@@@QEAA@XZ), на который есть ссылка в функции main
- Мои вопросы:
- что не так в моем дизайне?
- Есть ли лучший способ разработать рабочий процесс базы данных?
- Редактировать:
После прочтения ссылок, предоставленных Майлсом Буднеком, я понял, как на самом деле работают шаблоны, и я знаю, что у меня есть три варианта написания реализации класса шаблона:
Напишите реализацию непосредственно в заголовочном файле.
Записать реализацию в файл.cpp записать явные экземпляры в файл cpp.
- Запишите реализацию в файл.tpp и включите его в конец заголовочного файла.
Итак, я использовал второй метод и написал явную реализацию для использования класса model::SqliteDB: в конце DataBaseService.cpp
template class DatabaseService<model::SqliteDB>;
Это решило неразрешенную внешнюю ошибку! Но теперь у меня есть другая ошибка при попытке создать указатель IDatabase для объекта SQliteDB в DataBaseService.cpp в строке:
m_database = std::make_unique<T>();
Ошибки:
ошибка: жизнеспособный перегружен '='
ошибка: C2679: двоичный файл '=': не найден оператор, который принимает правый операнд типа 'std::unique_ptr>' (или нет приемлемого преобразования) с [ T=model::SqliteDB, _Ty=model::SqliteDB ]