Qt:未在范围中声明的自定义派生类

时间:2016-03-08 01:18:15

标签: c++ qt

Qt新手在这里遇到一个问题,它声称我没有声明一个我很确定已宣布的类。

我不能为我的生活弄清楚这一点。请帮忙。

在Connection.h和.cpp中注释出有问题的行会产生可编译的输出。

这是我的代码的精简版本,问题仍然存在:

顺便说一句,Map.ui只有拖入图形视图。

错误讯息:

In file included from ../Map/Map.h:17:0,
             from ../Map/City.cpp:1:
../Map/Connection.h:14:11: error: 'City' was not declared in this scope
     QPair<City*, City*> cities;
       ^
../Map/Connection.h:14:18: error: 'City' was not declared in this scope
     QPair<City*, City*> cities;
              ^
../Map/Connection.h:14:23: error: template argument 1 is invalid
     QPair<City*, City*> cities;
                   ^
../Map/Connection.h:14:23: error: template argument 2 is invalid
../Map/Connection.h:19:22: error: 'City' was not declared in this scope
     Connection(QPair<City*, City*> cities, int cost);
                  ^
../Map/Connection.h:19:29: error: 'City' was not declared in this scope
     Connection(QPair<City*, City*> cities, int cost);
                         ^
../Map/Connection.h:19:34: error: template argument 1 is invalid
     Connection(QPair<City*, City*> cities, int cost);

Map.pro:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Map
TEMPLATE = app

SOURCES +=\
    City.cpp \
    Connection.cpp \
    Map.cpp \
    Driver.cpp

HEADERS  += \
    City.h \
    Connection.h \
    Map.h

FORMS    += \
    Map.ui

Map.h:

#ifndef MAP_H
#define MAP_H

#include <QApplication>
#include <QGraphicsItem>
#include <QMainWindow>
#include <QtCore>
#include <QtGui>
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
#include <QDebug>
#include <QPainter>
#include <QString>
#include <QVector>

#include "ui_Map.h"
#include "Connection.h"
#include "City.h"

namespace Ui
{
    class Map;
}

class Map : public QMainWindow
{
    Q_OBJECT

public:
    explicit Map(QWidget *parent = 0);
    ~Map();

private:
    Ui::Map *ui;
    QGraphicsScene *scene;
};

#endif // MAP_H

Map.cpp:

#include "Map.h"
#include "ui_Map.h"

Map::Map(QWidget *parent) : QMainWindow(parent), ui(new Ui::Map)
{
    ui->setupUi(this);

    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);

    City *c1 = new City(30, 30, 30, "K");
    City *c2 = new City(30, 90, 30, "O");

    Connection *conn1 = new Connection(45, 45, 45, 105, 1);

    c1->setZValue(4);
    c2->setZValue(4);
    conn1->setZValue(2);

    scene->addItem(c1);
    scene->addItem(c2);
    scene->addItem(conn1);
}

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

City.h:

#ifndef CITY_H
#define CITY_H

#include "Map.h"

class City : public QGraphicsItem
{
private:
    int x;
    int y;
    int r;
    QString name;
    QRectF bounds;
    QVector<QPair<City*, int> > neighbors;

public:
    City();
    City(int x, int y, int r, QString name);
    int getX() { return this->x; }
    int getY() { return this->y; }
    int getR() { return this->r; }
    QString getName() { return this->name; }
    QVector<QPair<City*, int> > getNeighbors() { return this->neighbors; }
    void setNeighbors(QVector<QPair<City*, int> >) { this->neighbors = neighbors; }
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

};

#endif // CITY_H

City.cpp:

#include "Map.h"

City::City()
{
    this->bounds = QRectF(0, 0, 0, 0);
}

City::City(int x, int y, int r, QString name)
{
    this->x = x;
    this->y = y;
    this->r = r;
    this->name = name;
    this->bounds = QRectF(x, y, r, r);
}

QRectF City::boundingRect() const
{
    return QRectF(x, y, r, r);
}

void City::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QRectF rec;

    if (this->bounds == QRectF(0, 0, 0, 0))
    rec = boundingRect();
    else
    rec = this->bounds;

    QBrush brush(Qt::blue);
    QPen pen(Qt::blue);

    painter->setBrush(brush);
    painter->setPen(pen);
    painter->drawEllipse(rec);
}

Connection.h:

#ifndef CONNECTION_H
#define CONNECTION_H

#include "Map.h"

class Connection : public QGraphicsItem
{

private:
    int x1, x2;
    int y1, y2;
    int cost;
    QRectF bounds;
    QPair<City*, City*> cities;         // PROBLEMATIC LINE -- CLAIMS CITY WAS NOT DECLARED

public:
    Connection();
    Connection(int x1, int y1, int x2, int y2, int cost);
    Connection(QPair<City*, City*> cities, int cost);         // PROBLEMATIC LINE -- CLAIMS CITY WAS NOT DECLARED
    int getCost() { return this->cost; }
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};


#endif // CONNECTION_H

Connection.cpp:

#include "Map.h"

Connection::Connection()
{
    this->bounds = QRectF(0, 0, 0, 0);
}

Connection::Connection(int x1, int y1, int x2, int y2, int cost)
{
    this->x1 = x1;
    this->x2 = x2;
    this->y1 = y1;
    this->y2 = y2;

    this->bounds = QRectF(x1, x2, y1, y2);

}

Connection::Connection(QPair<City*, City*> cities, int cost)    // PROBLEMATIC BLOCK
{
    int r = cities.first->getR();
    this->x1 = cities.first->getX() + r/2;
    this->x2 = cities.second->getX() + r/2;
    this->y1 = cities.first->getY() + r/2;
    this->y2 = cities.second->getY() + r/2;

    this->cost = cost;

    this->bounds = QRectF(x1, x2, y1, y2);
}

QRectF Connection::boundingRect() const
{
    return QRectF(0, 0, 0, 0);
}

void Connection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QRectF rec;

    if (this->bounds == QRectF(0, 0, 0, 0))
    rec = boundingRect();
    else
    rec = this->bounds;

    QBrush brush(Qt::red);
    QPen pen(Qt::red);

    painter->setPen(pen);
    painter->drawLine(QLine(this->x1, this->y1, this->x2, this->y2));
}

Driver.cpp:

#include "Map.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Map w;
    w.show();

    return a.exec();
}

感谢您抽出宝贵时间来看看这个。我感谢任何反馈。有问题的线条可以编译一段时间,但似乎添加某些东西“打破”它。

this线程的答案让我觉得它可能是愚蠢的,但我改变事物顺序的尝试并没有解决它。

1 个答案:

答案 0 :(得分:3)

只要查看错误消息,就可以看到City类确实没有在Connection中定义。

In file included from ../Map/Map.h:17:0,
             from ../Map/City.cpp:1:

City.cpp以#include "Map.h"开始,这是奇怪的,因为cpp文件中没有对Map类型的引用。 City.cpp应该以{{1​​}}开头。

City.h以#include "City.h"开头,这甚至更奇怪,因为City类没有提到Map。

所以此时City.cpp:1 - &gt; Map.h:17你包括“Connection.h”。此时,没有已定义的类型。不是城市,而不是地图。编译器在没有定义类型的情况下接近 Connection 类。

修复它:

很难猜测你的依赖关系实际上是什么样的,但这个特定包含的一个解决方案可能是。

  • 首先在City.cpp中包含City.h。对于所有X.cpp文件,您应该#include "Map.h"
  • 从City.h文件中删除#include "X.h"
  • 如果City.cpp中需要Map类型,请将其包括在内。
  • 由于指针,Connection.h显然至少需要一个前向声明的类#include "Map.h"。所以要么做前瞻声明,要么做“#include”City.h“

总之:只包含您的类实际需要的标头中的文件。在相应的cpp中,首先包括标题。实现还需要头部所需的任何类型。之后,您将包含实现所需的其他类型。