Qt 项目中的前向声明
Forward declaration in Qt project
我正在尝试将 Qt 与 C++ 结合使用。我以前在Python用QT编程。
我的简单测试不起作用。这是我的 tour.h 文件:
#ifndef TOUR_H
#define TOUR_H
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QTableView>
class TourTable;
class Tour : public QMainWindow
{
Q_OBJECT
public:
Tour();
/*protected:
void closeEvent(QCloseEvent *event);
private slots:
void newCompetitor();
void remCompetitor();
void finalReport();
void openPage();
void savePage();
void reloadTitle();*/
private:
TourTable _table;
};
class QStandardItem;
class QStandardItemModel;
class TourTable : public QTableView
{
Q_OBJECT
public:
TourTable();
/* bool isChanged();
QString windowName();
void finalReport();
void newCompetitor();
void remCompetitor();
bool savePage();
void setChanged(bool value);
void openPage();
protected:
void itemChanged(QStandardItem item);
private:*/
// bool _secondBetter(p1, p2);
Tour _parent;
// QStandardItemModel _model;
// bool _saved;
// bool _changed;
};
#endif
我几乎对这段代码中的所有内容都进行了注释以找出问题所在,但我仍然不知道是什么原因造成的。我第一次尝试使用 C++。
错误信息是:
tour.h:28:12: error: field ‘_table’ has incomplete type ‘TourTable’
TourTable _table;
^~~~~~
tour.h:7:7: note: forward declaration of ‘class TourTable’
class TourTable;
谁能帮我解决这个问题?
明确地说,这个错误来自您的编译器——而不是来自 qmake——并且是语言的限制。但它可以通过创建一个 class 来轻松克服,它定义了一个 parent/child 行为,并在你希望该行为从基础 class 继承的任何地方创建任何 classes,如 Qt 的QObject 确实如此。
QMainWindow
和QTableView
都继承自QObject
,所以如果你使用QObject
的parent/child系统,这个设计可能是多余的。从子调用 parent(), and to find the children from the parent you can call children().
中找到父
C++ 中的前向声明允许在定义之前引用类型。这里的问题是在你的代码中:
class TourTable;
class Tour : public QMainWindow
{
// ...
TourTable _table;
};
您不仅引用了类型 TourTable
,还用 TourTable _table;
对其进行了实例化。这需要TourTable
.
的完整定义
一个解决方案可以是在Tour
之前定义TourTable
,如下:
class TourTable : public QTableView
{
// ...
Tour _parent;
}
class Tour : public QMainWindow
{
// ...
TourTable _table;
};
但这只会解决问题,因为您在 TourTable
中实例化 Tour
。
根据完整的设计,解决方案可能是使用指针。类似的东西:
class TourTable;
class Tour : public QMainWindow
{
Tour();
// forward declaration of the constructor,
// see below for the definition
TourTable* _table;
// no complete definition of TourTable at this stage,
// only a forward declaration:
// we can only declare a pointer
};
class TourTable : public QTableView
{
TourTable(Tour* parent):
QTableView(parent),
_parent(parent)
{
}
Tour* _parent;
}
Tour::Tour() // definition of Tour's constructor
{
_table = new TourTable(this);
// TourTable has been defined : we can instantiate it here
}
我正在尝试将 Qt 与 C++ 结合使用。我以前在Python用QT编程。
我的简单测试不起作用。这是我的 tour.h 文件:
#ifndef TOUR_H
#define TOUR_H
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QTableView>
class TourTable;
class Tour : public QMainWindow
{
Q_OBJECT
public:
Tour();
/*protected:
void closeEvent(QCloseEvent *event);
private slots:
void newCompetitor();
void remCompetitor();
void finalReport();
void openPage();
void savePage();
void reloadTitle();*/
private:
TourTable _table;
};
class QStandardItem;
class QStandardItemModel;
class TourTable : public QTableView
{
Q_OBJECT
public:
TourTable();
/* bool isChanged();
QString windowName();
void finalReport();
void newCompetitor();
void remCompetitor();
bool savePage();
void setChanged(bool value);
void openPage();
protected:
void itemChanged(QStandardItem item);
private:*/
// bool _secondBetter(p1, p2);
Tour _parent;
// QStandardItemModel _model;
// bool _saved;
// bool _changed;
};
#endif
我几乎对这段代码中的所有内容都进行了注释以找出问题所在,但我仍然不知道是什么原因造成的。我第一次尝试使用 C++。
错误信息是:
tour.h:28:12: error: field ‘_table’ has incomplete type ‘TourTable’
TourTable _table;
^~~~~~
tour.h:7:7: note: forward declaration of ‘class TourTable’
class TourTable;
谁能帮我解决这个问题?
明确地说,这个错误来自您的编译器——而不是来自 qmake——并且是语言的限制。但它可以通过创建一个 class 来轻松克服,它定义了一个 parent/child 行为,并在你希望该行为从基础 class 继承的任何地方创建任何 classes,如 Qt 的QObject 确实如此。
QMainWindow
和QTableView
都继承自QObject
,所以如果你使用QObject
的parent/child系统,这个设计可能是多余的。从子调用 parent(), and to find the children from the parent you can call children().
C++ 中的前向声明允许在定义之前引用类型。这里的问题是在你的代码中:
class TourTable;
class Tour : public QMainWindow
{
// ...
TourTable _table;
};
您不仅引用了类型 TourTable
,还用 TourTable _table;
对其进行了实例化。这需要TourTable
.
一个解决方案可以是在Tour
之前定义TourTable
,如下:
class TourTable : public QTableView
{
// ...
Tour _parent;
}
class Tour : public QMainWindow
{
// ...
TourTable _table;
};
但这只会解决问题,因为您在 TourTable
中实例化 Tour
。
根据完整的设计,解决方案可能是使用指针。类似的东西:
class TourTable;
class Tour : public QMainWindow
{
Tour();
// forward declaration of the constructor,
// see below for the definition
TourTable* _table;
// no complete definition of TourTable at this stage,
// only a forward declaration:
// we can only declare a pointer
};
class TourTable : public QTableView
{
TourTable(Tour* parent):
QTableView(parent),
_parent(parent)
{
}
Tour* _parent;
}
Tour::Tour() // definition of Tour's constructor
{
_table = new TourTable(this);
// TourTable has been defined : we can instantiate it here
}