Указатель базового класса, указывающий на объект производного класса, который является переменной шаблона в другом классе

Извините, если название не ясно. Но я постараюсь объяснить проблему ясно.


Я работаю на 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

- Мои вопросы:

  1. что не так в моем дизайне?
  2. Есть ли лучший способ разработать рабочий процесс базы данных?

- Редактировать:
После прочтения ссылок, предоставленных Майлсом Буднеком, я понял, как на самом деле работают шаблоны, и я знаю, что у меня есть три варианта написания реализации класса шаблона:

  1. Напишите реализацию непосредственно в заголовочном файле.

  2. Записать реализацию в файл.cpp записать явные экземпляры в файл cpp.

  3. Запишите реализацию в файл.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 ]

0 ответов

Другие вопросы по тегам