为什么一个看似定义正确的类却无法被识别?

发布于 2025-01-11 08:08:02 字数 6695 浏览 0 评论 0原文

我正在开发 Qt Creator 电影推荐项目,并且遇到继承/多态性问题。我的项目没有将我的具体策略类(SortLeadActor)识别为我的策略类(Sort)的子类。任何有关如何解决此问题的反馈将不胜感激:)

策略设计模式的上下文类:

#ifndef TABLEFILTER_H
#define TABLEFILTER_H

#include <iostream>
#include "Sort.h"

class TableFilter
{
public:
    TableFilter(Sort* s, QString title)
    {
        strategy = s;
        movieTitle = title;
    }

    ~TableFilter()
    {
        delete strategy;
    }

    void filter()
    {
        strategy->appliedSort(movieTitle);
    }

    void SetSort(Sort* const newStrat)
    {
        strategy = newStrat;
    }

private:
    Sort *strategy;
    QString movieTitle;
};

#endif // TABLEFILTER_H

策略类:

#include <QSqlQuery>
#include <QString>

#include "mainwindow.h"

class Sort //Strategy
{
public:
    Sort()
    {
        filterType = mainWindow.getFilterType();

        switch(filterType)
        {
            case 0: //Genre;
            case 1: //LA;
            case 2: //SA;
            case 3: //Dir;
            case 4: //Release Year;
            case 5: //IMBD Score;
            case 6: //Content Rating;
            ;
        }
    }

    virtual ~Sort() {}

    virtual void appliedSort(QString title) = 0;

 private:
    MainWindow mainWindow;
    int filterType;
};

#endif // SORT_H

具体策略类:

#ifndef SORTLEADACTOR_H
#define SORTLEADACTOR_H

#include "Sort.h"
#include "mainwindow.h"

class SortLeadActor : public Sort //Concrete Strategy
{
public:
    SortLeadActor();

    void appliedSort(QString title);

private:
    QSqlQueryModel* model;
    QSqlQuery* qry;
    QString leadActor;
    MainWindow *mainWindow;
    QString filterType;
};

#endif // SORTLEADACTOR_H
#include "sortleadactor.h"

SortLeadActor::SortLeadActor()
{

}

void SortLeadActor::appliedSort(QString title)
{
    this->model = new QSqlQueryModel();
    this->qry = new QSqlQuery();

    this->qry->prepare("SELECT Actor_1 FROM movie_metadata WHERE Movie_Title = :movieTitle");
    this->qry->bindValue(":movieTitle", title);

    this->qry->exec();

    while (qry->next())
    {
        leadActor = qry->value(0).toString();
    }

    this->qry->prepare("SELECT * FROM movie_metadata WHERE Actor_1 = :leadingActor");
    this->qry->bindValue(":leadingActor", leadActor);

    this->qry->exec();

    //Assign query to model
    model->setQuery(*qry);

    mainWindow->setTableModel(model);
}

MainWindow 类,我试图在其中创建 SortLeadActor 类型的 Sort*

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "database.h"
#include "tablefilter.h"
#include "Sort.h"
#include "sortleadactor.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    /**
    * @brief Class Method to update and show all movie info
    *
    * updates query for entire movie info chart and sets ui Model
    */
    void displayAllMovies();

    void setTableModel(QAbstractItemModel *model);

    int getFilterType();

private slots:
    void on_pushButtonViewMovies_clicked();

    void on_lineEdit_textEdited(const QString &arg1);

    void on_pushButton_filter_clicked();

    void on_pushButtonFilterView_clicked();

private:
    Ui::MainWindow *ui;

    /**
    * @brief assigns myDb to predefined PROJECT_PATH constant
    */
    Database myDb = Database(PROJECT_PATH + "/MovieDatabase/movie.db");
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->stackedWidget->setCurrentIndex(0);

    //Check if database is open
    if(!myDb.isOpen())
    {
        qDebug() << "DATABASE FAILED TO OPEN" << Qt::endl;
    }
    else
    {
        qDebug() << "DATABASE SUCCESSFULLY CONNECTED" << Qt::endl;
        displayAllMovies();
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::displayAllMovies()
{
    QSqlQueryModel* model = new QSqlQueryModel();

    QSqlQuery* qry = new QSqlQuery();

    qry->prepare("SELECT Movie_Title, Director_Name, Actor_1, "
                 "Actor_2, Actor_3, Genres, Content_Rating, "
                 "Title_Year FROM movie_metadata");

    if(!(qry->exec()))
    {
        qDebug() << "query did not execute" << Qt::endl;
    }

    model->setQuery(*qry);

    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}


void MainWindow::on_pushButtonViewMovies_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
}

void MainWindow::on_lineEdit_textEdited(const QString &arg1)
{
    //Create Database model
    QSqlQueryModel* model = new QSqlQueryModel();
    //Create Database query
    QSqlQuery* qry = new QSqlQuery();

    //Prepare query with search conditions
    qry->prepare("SELECT Movie_Title, Director_Name, Actor_1, "
                 "Actor_2, Actor_3, Genres, Content_Rating, "
                 "Title_Year FROM movie_metadata WHERE Movie_Title LIKE :search");
    qry->bindValue(":search", QString("%%1%").arg(arg1));

    //Execute query command
    if(!(qry->exec()))
    {
        qDebug() << "query did not execute" << Qt::endl;
    }

    //Retrieve previous model
    QItemSelectionModel* temp = ui->MovieTableView->selectionModel();
    temp->clear();

    //Assign query to model
    model->setQuery(*qry);

    //Delete previous model
    delete temp;

    //Change TableView to new model
    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}

void MainWindow::on_pushButton_filter_clicked()
{
    ui->stackedWidget->setCurrentIndex(2);
}

void MainWindow::setTableModel(QAbstractItemModel *model)
{
    //Change TableView to new model
    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}

void MainWindow::on_pushButtonFilterView_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
    Sort *leadActor =  new SortLeadActor();
    QString name = "Avatar";
    TableFilter filterLA(leadActor, name);
}

int MainWindow::getFilterType()
{
    return ui->comboBoxFilter->currentIndex();
}

错误发生在该特定行上MainWindow.cpp:

Sort *leadActor =  new SortLeadActor();

错误消息指出:“mainwindow.cpp:104:11:错误:无法使用“SortLeadActor *”类型的右值初始化“Sort *”类型的变量”

I am working on a Qt Creator Movie Recommender Project, and I am having an issue with inheritance/polymorphism. My project is not recognizing my concrete strategy class(SortLeadActor) as a subclass of my strategy class(Sort). Any feedback on how to fix this issue would be greatly appreciated :)

Context Class for Strategy design pattern:

#ifndef TABLEFILTER_H
#define TABLEFILTER_H

#include <iostream>
#include "Sort.h"

class TableFilter
{
public:
    TableFilter(Sort* s, QString title)
    {
        strategy = s;
        movieTitle = title;
    }

    ~TableFilter()
    {
        delete strategy;
    }

    void filter()
    {
        strategy->appliedSort(movieTitle);
    }

    void SetSort(Sort* const newStrat)
    {
        strategy = newStrat;
    }

private:
    Sort *strategy;
    QString movieTitle;
};

#endif // TABLEFILTER_H

Strategy Class:

#include <QSqlQuery>
#include <QString>

#include "mainwindow.h"

class Sort //Strategy
{
public:
    Sort()
    {
        filterType = mainWindow.getFilterType();

        switch(filterType)
        {
            case 0: //Genre;
            case 1: //LA;
            case 2: //SA;
            case 3: //Dir;
            case 4: //Release Year;
            case 5: //IMBD Score;
            case 6: //Content Rating;
            ;
        }
    }

    virtual ~Sort() {}

    virtual void appliedSort(QString title) = 0;

 private:
    MainWindow mainWindow;
    int filterType;
};

#endif // SORT_H

Concrete Strategy Class:

#ifndef SORTLEADACTOR_H
#define SORTLEADACTOR_H

#include "Sort.h"
#include "mainwindow.h"

class SortLeadActor : public Sort //Concrete Strategy
{
public:
    SortLeadActor();

    void appliedSort(QString title);

private:
    QSqlQueryModel* model;
    QSqlQuery* qry;
    QString leadActor;
    MainWindow *mainWindow;
    QString filterType;
};

#endif // SORTLEADACTOR_H
#include "sortleadactor.h"

SortLeadActor::SortLeadActor()
{

}

void SortLeadActor::appliedSort(QString title)
{
    this->model = new QSqlQueryModel();
    this->qry = new QSqlQuery();

    this->qry->prepare("SELECT Actor_1 FROM movie_metadata WHERE Movie_Title = :movieTitle");
    this->qry->bindValue(":movieTitle", title);

    this->qry->exec();

    while (qry->next())
    {
        leadActor = qry->value(0).toString();
    }

    this->qry->prepare("SELECT * FROM movie_metadata WHERE Actor_1 = :leadingActor");
    this->qry->bindValue(":leadingActor", leadActor);

    this->qry->exec();

    //Assign query to model
    model->setQuery(*qry);

    mainWindow->setTableModel(model);
}

MainWindow Class where I am trying to create a Sort* of type SortLeadActor

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "database.h"
#include "tablefilter.h"
#include "Sort.h"
#include "sortleadactor.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    /**
    * @brief Class Method to update and show all movie info
    *
    * updates query for entire movie info chart and sets ui Model
    */
    void displayAllMovies();

    void setTableModel(QAbstractItemModel *model);

    int getFilterType();

private slots:
    void on_pushButtonViewMovies_clicked();

    void on_lineEdit_textEdited(const QString &arg1);

    void on_pushButton_filter_clicked();

    void on_pushButtonFilterView_clicked();

private:
    Ui::MainWindow *ui;

    /**
    * @brief assigns myDb to predefined PROJECT_PATH constant
    */
    Database myDb = Database(PROJECT_PATH + "/MovieDatabase/movie.db");
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->stackedWidget->setCurrentIndex(0);

    //Check if database is open
    if(!myDb.isOpen())
    {
        qDebug() << "DATABASE FAILED TO OPEN" << Qt::endl;
    }
    else
    {
        qDebug() << "DATABASE SUCCESSFULLY CONNECTED" << Qt::endl;
        displayAllMovies();
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::displayAllMovies()
{
    QSqlQueryModel* model = new QSqlQueryModel();

    QSqlQuery* qry = new QSqlQuery();

    qry->prepare("SELECT Movie_Title, Director_Name, Actor_1, "
                 "Actor_2, Actor_3, Genres, Content_Rating, "
                 "Title_Year FROM movie_metadata");

    if(!(qry->exec()))
    {
        qDebug() << "query did not execute" << Qt::endl;
    }

    model->setQuery(*qry);

    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}


void MainWindow::on_pushButtonViewMovies_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
}

void MainWindow::on_lineEdit_textEdited(const QString &arg1)
{
    //Create Database model
    QSqlQueryModel* model = new QSqlQueryModel();
    //Create Database query
    QSqlQuery* qry = new QSqlQuery();

    //Prepare query with search conditions
    qry->prepare("SELECT Movie_Title, Director_Name, Actor_1, "
                 "Actor_2, Actor_3, Genres, Content_Rating, "
                 "Title_Year FROM movie_metadata WHERE Movie_Title LIKE :search");
    qry->bindValue(":search", QString("%%1%").arg(arg1));

    //Execute query command
    if(!(qry->exec()))
    {
        qDebug() << "query did not execute" << Qt::endl;
    }

    //Retrieve previous model
    QItemSelectionModel* temp = ui->MovieTableView->selectionModel();
    temp->clear();

    //Assign query to model
    model->setQuery(*qry);

    //Delete previous model
    delete temp;

    //Change TableView to new model
    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}

void MainWindow::on_pushButton_filter_clicked()
{
    ui->stackedWidget->setCurrentIndex(2);
}

void MainWindow::setTableModel(QAbstractItemModel *model)
{
    //Change TableView to new model
    ui->MovieTableView->setModel(model);
    ui->MovieTableView->resizeColumnsToContents();
}

void MainWindow::on_pushButtonFilterView_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
    Sort *leadActor =  new SortLeadActor();
    QString name = "Avatar";
    TableFilter filterLA(leadActor, name);
}

int MainWindow::getFilterType()
{
    return ui->comboBoxFilter->currentIndex();
}

Error is happening on this specific line in MainWindow.cpp:

Sort *leadActor =  new SortLeadActor();

Error message states: "mainwindow.cpp:104:11: error: cannot initialize a variable of type 'Sort *' with an rvalue of type 'SortLeadActor *'"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百合的盛世恋 2025-01-18 08:08:02

原因

当您编写 include 语句时,编译器会将其替换为包含的头文件的内容。考虑到这一点,让我们看看您实际上在做什么:

sort.h 中包含 mainwindow.h 并在 mainwindow.h 中包含sort.h

这就像站在两个平行的镜子之间。你会得到无限的反思。

解决方案

在一般情况下,使用前向声明来避免此问题。例如:

Foo.h

class Bar;

class Foo {
    Bar *m_bar;
};

Bar.h

class Foo;

class Bar {
    Foo *m_foo;
};

Foo.cpp

#include "Foo.h"
#include "Bar.h"
...

Bar.cpp

#include "Bar.h"
#include "Foo.h"
...

在您的特定情况下,它可能是有必要重新设计您的软件架构。我怀疑您是否真的需要前端(MainWindow mainWindow;)作为后端(Sort)的私有成员。

Cause

When you write an include-statement the compiler replaces it with the content of the included header file. With this in mind, let's see what you are actually doing:

In sort.h you include mainwindow.h and in mainwindow.h you include sort.h.

This is like standing between two parallel mirrors. You get infinite reflections.

Solution

In the general case a forward declaration is used to avoid this problem. For instance:

Foo.h

class Bar;

class Foo {
    Bar *m_bar;
};

Bar.h

class Foo;

class Bar {
    Foo *m_foo;
};

Foo.cpp

#include "Foo.h"
#include "Bar.h"
...

Bar.cpp

#include "Bar.h"
#include "Foo.h"
...

In your particular case it might be neccessary to redesign your software architecture. I doubt that you really need the frontend (MainWindow mainWindow;) as private member of the backend (Sort).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文