为什么一个看似定义正确的类却无法被识别?
我正在开发 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
原因
当您编写
include
语句时,编译器会将其替换为包含的头文件的内容。考虑到这一点,让我们看看您实际上在做什么:在
sort.h
中包含mainwindow.h
并在mainwindow.h
中包含sort.h
。这就像站在两个平行的镜子之间。你会得到无限的反思。
解决方案
在一般情况下,使用前向声明来避免此问题。例如:
Foo.h
Bar.h
Foo.cpp
Bar.cpp
在您的特定情况下,它可能是有必要重新设计您的软件架构。我怀疑您是否真的需要前端(
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 includemainwindow.h
and inmainwindow.h
you includesort.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
Bar.h
Foo.cpp
Bar.cpp
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
).