无效地使用不完整类型和前向声明

Invalid use of incomplete type and forward declaration

本文关键字:声明 类型 用不完 无效      更新时间:2023-10-16

我试图解决这个问题,但是我对forward声明的理解一定有一些误解。

我得到以下错误:

src/algorithm.cpp: In constructor ‘Algorithm::Algorithm(MainWindow*)’:
src/algorithm.cpp:22:20: error: invalid use of incomplete type ‘struct Ui::MainWindow’
src/mainwindow.h:23:10: error: forward declaration of ‘struct Ui::MainWindow’

我有这些文件(我提交了一些行和文件,只粘贴了相关的代码):

algorithm.cpp

#include "algorithm.h"
#include "mainwindow.h"
Algorithm::Algorithm(MainWindow *mainWindow)
{
   this->mainWindow = mainWindow;
   QAction *action = new QAction(this);
   action->setObjectName(QStringLiteral("action"));
   action->setText(this->getName());
   mainWindow->m_ui->menuAlgorithms->addAction(action);
   mainWindow->connect(action, SIGNAL(triggered()), this, SLOT(this->start()));
}

algorithm.h

#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <QObject>
#include "graphwidget.h"
#include "edge.h"
#include "vertex.h"
class MainWindow;
class Algorithm : public QObject
{
public:
   MainWindow *mainWindow;
   Algorithm(MainWindow *mainWindow);
   void start();
   virtual void solve();
   virtual QString getDescription();
   virtual QString getName();
};

mainwindow.cpp

#include "mainwindow.h"
#include "algorithm.h"
#include "../ui/ui_mainwindow.h"
#include "vertex.h"
#include "edge.h"
#include "warning.h"
mode_type mode;
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   m_ui(new Ui::MainWindow)
{
   gundirected = NULL;
   gdirected = NULL;
   m_ui->setupUi(this);
...

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QSignalMapper>
#include <QUndoView>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QKeyEvent>
#include <QGraphicsSceneMouseEvent>
#include <QLabel>
#include <QVBoxLayout>
#include <QPushButton>
#include "graphwidget.h"
enum mode_type {NORMAL, VERTEX, EDGE}; // vyctovy typ pro urceni editoacniho modu
extern mode_type mode;
namespace Ui
{
   class MainWindow;
}
class MainWindow : public QMainWindow
{
   Q_OBJECT
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
   Ui::MainWindow *m_ui;
...

代码中的问题是,您试图在Algorithm类中使用MainWindow类的m_ui成员,并且m_ui的类型是Ui::MainWindow,但是您的Algorithm类不知道这种类型。您可以通过在algorithm.cpp中包含ui_mainwindow.h来解决这个问题。

但这仍然是糟糕的设计。m_ui应该是MainWindow类的私有成员。您不应该从其他类访问它。相反,在MainWindow类中创建函数,允许您做您想做的事情。

例如,创建如下的公共函数:

void MainWindow::addCustomAction(QAction *action)
{
    m_ui->menuAlgorithms->addAction(action);
}

然后从你的Algorithm类调用这个函数:

Algorithm::Algorithm(MainWindow *mainWindow)
{
   this->mainWindow = mainWindow;
   QAction *action = new QAction(this);
   action->setObjectName(QStringLiteral("action"));
   action->setText(this->getName());
   mainWindow->addCustomAction(action);
   connect(action, SIGNAL(triggered()), this, SLOT(start()));
}

您的forward声明出现在名称空间UI中,但是您的类声明出现在该名称空间之外。您应该将其更改为

 namespace UI {
     class MainWindow : public QMainWindow {
         Q_OBJECT
         // ...
     };
 }

似乎你也不需要在那里提供一个前向声明,但再次改变Algorithm.h中的前向声明,使MainWindow出现在正确的命名空间中:

 namespace UI {
     class MainWindow;
 }