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

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


Я работаю над c ++ и QT с использованием MVC для архитектуры приложения:

enter image description here

- Некоторые описания структуры приложения:

  • Раздел модели (разработан с использованием шаблона полиморфизма):

    отвечает за вещи, связанные с базой данных, имеет 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;
    };
    

    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;
    };
    
  • Секция контроллера : Я использую шаблонный класс 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. wriРеализация в файле .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 = модель :: SqliteDB, _Ty = модель :: SqliteDB]

...