不合法的使用不完整类型和前向声明。

4
我正在尝试解决这个问题,但我对前向声明的理解可能存在一些误解。
我遇到了以下错误:
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;
...
2个回答

4

你的前向声明出现在命名空间UI中,但是你的类声明出现在这个命名空间之外。你应该将其更改为

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

看起来在那里您不需要提供前向声明,但需要再次更改Algorithm.h中的前向声明以出现在正确命名空间中:MainWindow

 namespace UI {
     class MainWindow;
 }

现在我得到了src/main.cpp:15:15的错误:错误:聚合体‘MainWindow window’类型不完整,无法定义。 - alop789312
@jb91 你需要为你的定义指定命名空间。可以将所有的定义都放在你的 .cpp 文件中的 namespace UI { ... } 中,或者在所有的定义之前提供一个 using 语句和 using UI::MainWindow; - πάντα ῥεῖ
1
这不是它应该工作的方式。Ui::MainWindowMainWindow不同。Ui::MainWindow类在ui_mainwindow.h文件中声明。问题在于他试图在未包含ui_mainwindow.h头文件的情况下从Algorithm类中使用Ui::MainWindow - thuga
@thuga 我知道在 OP 的示例代码中存在更多的缺陷。我只是指出了最重要的问题需要解决。如果你愿意,可以添加另一个答案,深入探讨其他或后续的问题。 - πάντα ῥεῖ

4
你代码中的问题在于,你试图在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(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()));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接