Название: Проблема с #include
Отправлено: dware от Июня 07, 2010, 18:59
hello everybody! Использую в классе Arrow переменные типа Item и в классе Item переменные типа Arrow. Соответсвенно в Arrow.h пишу #include "Item.h", в Item.h пишу #include "Arrow.h", но при сборке в Arrow.h вылазит ошибка "Item has not been declared". Наверное, намудрил с include'ами. Помогите, пожалста. /////////////////////////////////////////////////////////// // Arrow.h // Implementation of the Class Arrow // Created on: 02-июн-2010 20:51:37 // Original author: ///////////////////////////////////////////////////////////
#ifndef ARROW_H #define ARROW_H
#include <QtGui> #include <QGraphicsLineItem> #include <QGraphicsScene>
#include "ArrowType.h" #include "Text.h" #include "Item.h"
class Arrow : public QGraphicsLineItem {
public: enum { Type = UserType + 2 }; Arrow(Item *startItem, Item *endItem, QGraphicsItem *parent, QGraphicsScene *scene);
QRectF boundingRect() const; void setColor(QColor color); void setNamePosition(Item * startItem, Item * endItem); void setEndItemRMPosition(Item * endItem); void setStartItemRMPosition(Item * startItem); void setName(Text * text); void setTargetRole(Text * text); void setSourceRole(Text * text); void setTargetMult(Text * text); void setSourceMult(Text * text); Item * endItem(); Item * startItem(); QPixmap image(ArrowType type) const; QPainterPath shape() const; void updatePosition();
protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) {return;} Item * myStartItem; Item * myEndItem; QPointF myStartPoint; QPointF myEndPoint; QPointF myNamePosition; QPointF myTargetRMPosition; QPointF mySourceRMPosition; ArrowType myArrowType; Text * myName; Text * myTargetRole; Text * mySourceRole; Text * myTargetMult; Text * mySourceMult; QColor myColor; QPolygonF arrowHead; };
#endif //ACTOR_H
////////////////////////////////////////////////////////// // Item.h // Implementation of the Class Item // Created on: 02-июн-2010 20:51:39 // Original author: ///////////////////////////////////////////////////////////
#ifndef ITEM_H #define ITEM_H
#include <QtGui> #include <QList> #include <QPolygonF> #include <QPainterPath> #include <QGraphicsPolygonItem> #include <QGraphicsScene>
#include "ItemType.h" #include "Text.h" #include "Arrow.h"
class Item : public QGraphicsPolygonItem { public: enum { Type = UserType + 1 }; Item(QGraphicsItem *parent, QGraphicsScene *scene);
void addArrow(Arrow * arrow); void removeArrow(Arrow * arrow); void removeArrows(); void setPosition(QPointF position); void setFillColor(QColor color); QPointF getPosition(); QPixmap image() const; int type() const { return Type;}
protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value); QList<Arrow *> myArrows; QPointF myPosition; QColor myFillColor; double myWidth; double myHeight; QPolygonF myPolygon; };
#endif //ITEM_H
In file included from Item.h:20, from Actor.h:13, from Scene.h:13, from mainwindow.h:7, from main.cpp:3: Arrow.h:24: error: expected ')' before '*' token Arrow.h:28: error: 'Item' has not been declared Arrow.h:28: error: 'Item' has not been declared Arrow.h:29: error: 'Item' has not been declared Arrow.h:30: error: 'Item' has not been declared Arrow.h:36: error: ISO C++ forbids declaration of 'Item' with no type Arrow.h:36: error: expected ';' before '*' token Arrow.h:37: error: ISO C++ forbids declaration of 'Item' with no type Arrow.h:37: error: expected ';' before '*' token Arrow.h:45: error: ISO C++ forbids declaration of 'Item' with no type Arrow.h:45: error: expected ';' before '*' token Arrow.h:46: error: ISO C++ forbids declaration of 'Item' with no type Arrow.h:46: error: expected ';' before '*' token
Название: Re: Проблема с #include
Отправлено: Rcus от Июня 07, 2010, 19:09
Перечитайте TC++PL SE § 5.7 или google://forward+declaration
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 19:18
5.7 - это Структуры, точно эта глава?
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 20:03
вот что почитал: http://www.forum.crossplatform.ru/index.php?showtopic=938
у меня эти два класса именно "явно/неявно" используют друг друга, значит, я не могу заменить #include "Arrow.h" на class Arrow (и для Item тоже самое, соотвественно).
Название: Re: Проблема с #include
Отправлено: BRE от Июня 07, 2010, 20:16
у меня эти два класса именно "явно/неявно" используют друг друга, значит, я не могу заменить #include "Arrow.h" на class Arrow (и для Item тоже самое, соотвественно).
Нет, ты можешь использовать forward declaration.
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 20:40
Да я бы с радостью :) void Item::removeArrows() { foreach (Arrow *arrow, myArrows) { arrow->startItem()->removeArrow(arrow); //Item.cpp:54: error: invalid use of incomplete type 'struct Arrow' arrow->endItem()->removeArrow(arrow); scene()->removeItem(arrow); delete arrow; } } class Arrow; //Item.h:20: error: forward declaration of 'struct Arrow' Уже часов 5 бьюсь головой об стену, где об этом всё-таки можно хорошенько почитать?
Название: Re: Проблема с #include
Отправлено: BRE от Июня 07, 2010, 20:42
#include "Item.h" // !!!
void Item::removeArrows() { foreach (Arrow *arrow, myArrows) { arrow->startItem()->removeArrow(arrow); //Item.cpp:54: error: invalid use of incomplete type 'struct Arrow' arrow->endItem()->removeArrow(arrow); scene()->removeItem(arrow); delete arrow; } }
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 20:49
это есть. вот так понятнее будет :) /////////////////////////////////////////////////////////// // Arrow.h // Implementation of the Class Arrow // Created on: 02-июн-2010 20:51:37 // Original author: ///////////////////////////////////////////////////////////
#ifndef ARROW_H #define ARROW_H
#include <QtGui> #include <QGraphicsLineItem> #include <QGraphicsScene>
#include "ArrowType.h" #include "Text.h" class Item;
class Arrow : public QGraphicsLineItem {
public: enum { Type = UserType + 2 }; Arrow(Item *startItem, Item *endItem, QGraphicsItem *parent, QGraphicsScene *scene);
QRectF boundingRect() const; void setColor(QColor color); void setNamePosition(Item * startItem, Item * endItem); void setEndItemRMPosition(Item * endItem); void setStartItemRMPosition(Item * startItem); void setName(Text * text); void setTargetRole(Text * text); void setSourceRole(Text * text); void setTargetMult(Text * text); void setSourceMult(Text * text); Item * endItem(); Item * startItem(); QPixmap image(ArrowType type) const; QPainterPath shape() const; void updatePosition();
protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) {return;} Item * myStartItem; Item * myEndItem; QPointF myStartPoint; QPointF myEndPoint; QPointF myNamePosition; QPointF myTargetRMPosition; QPointF mySourceRMPosition; ArrowType myArrowType; Text * myName; Text * myTargetRole; Text * mySourceRole; Text * myTargetMult; Text * mySourceMult; QColor myColor; QPolygonF arrowHead; };
#endif //ACTOR_H
////////////////////////////////////////////////////////// // Item.h // Implementation of the Class Item // Created on: 02-июн-2010 20:51:39 // Original author: ///////////////////////////////////////////////////////////
#ifndef ITEM_H #define ITEM_H
#include <QtGui> #include <QList> #include <QPolygonF> #include <QPainterPath> #include <QGraphicsPolygonItem> #include <QGraphicsScene>
#include "ItemType.h" #include "Text.h" class Arrow; //Item.h:20: error: forward declaration of 'struct Arrow'
class Item : public QGraphicsPolygonItem { public: enum { Type = UserType + 1 }; Item(QGraphicsItem *parent, QGraphicsScene *scene);
void addArrow(Arrow * arrow); void removeArrow(Arrow * arrow); void removeArrows(); void setPosition(QPointF position); void setFillColor(QColor color); QPointF getPosition(); QPixmap image() const; int type() const { return Type;}
protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value); QList<Arrow *> myArrows; QPointF myPosition; QColor myFillColor; double myWidth; double myHeight; QPolygonF myPolygon; };
#endif //ITEM_H
/////////////////////////////////////////////////////////// // Arrow.cpp // Implementation of the Class Arrow // Created on: 02-июн-2010 20:51:38 // Original author: ///////////////////////////////////////////////////////////
#include <QtGui>
#include "Arrow.h"
const qreal Pi = 3.14;
Arrow::Arrow(Item *startItem, Item *endItem, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsLineItem(parent, scene) { setFlag(QGraphicsItem::ItemIsSelectable, true); myColor = Qt::black; myName = new Text; myTargetRole = new Text; mySourceRole = new Text; myTargetMult = new Text; mySourceMult = new Text; }
QPixmap Arrow::image(ArrowType type) const { QPixmap pixmap(250,250); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.translate(125, 125);
switch (type) { case (AssotiationType): painter.setPen(QPen(Qt::black, 8, Qt::SolidLine)); painter.drawLine(-60,-60,60,60); break; case (DependencyType): painter.setPen(QPen(Qt::black, 8, Qt::DashLine)); painter.drawLine(-60,-60,60,60); painter.setPen(QPen(Qt::black, 8, Qt::SolidLine)); painter.drawLine(60,60,60,10); painter.drawLine(10,60,60,60); break; case (RealizationType): painter.setPen(QPen(Qt::black, 8, Qt::DashLine)); painter.drawLine(-60,-60,60,60); painter.setPen(QPen(Qt::black, 8, Qt::SolidLine)); painter.drawLine(60,60,60,10); painter.drawLine(60,10,10,60); painter.drawLine(10,60,60,60); break; case (CommentLinkType): painter.setPen(QPen(Qt::black, 8, Qt::DotLine)); painter.drawLine(-60,-60,60,60); break; }
return pixmap; }
//QRectF QRectF::normalized() const - возвращает нормализованный прямоугольник //т.е. прямоугольник, который имеет неотрицательные ширину и высоту //Если width()<0 (ширина отрицательна), функция меняет местами левые и правые //углы, если height()<0 (высота отрицательна), то функция меняет местами //верхние и нижние углы //QRectF QRectF::adjusted (qreal dx1, qreal dy1, qreal dx2, qreal dy ) const - //возвращает новый прямоугольник, с dx1,dy1,dx2,dy2 добавленными к соот- //ветствующм координатам *этого* прямоугольника. QRectF Arrow::boundingRect() const { qreal extra = (pen().width() + 20) / 2.0;
return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(), line().p2().y() - line().p1().y())) .normalized() .adjusted(-extra, -extra, extra, extra); }
//QPainterPath QGraphicsItem::shape() const [virtual] - возвращает форму //*этого* элемента как QPainterPath в локальных координатах //void QPainterPath::addPolygon (const QPolygonF & polygon) - добавляет //заданный многоугольник polygon в траекторию как подтраекторию QPainterPath Arrow::shape() const { QPainterPath path = QGraphicsLineItem::shape(); path.addPolygon(arrowHead); return path; }
//QPointF QGraphicsItem::mapFromItem (const QGraphicsItem *item, const QPointF &point) const //"картирует" точку point в системе координат элемента item в координатную //систему *этого* элемента и возвращает картированные координаты //В данном случае точка 0,0 элемента myStartItem соединяется линией //с точкой 0,0 элемента myEndItem //void QGraphicsLineItem::setLine(const QLineF &line) void Arrow::updatePosition() { QLineF line(mapFromItem(myStartItem, 0, 0), mapFromItem(myEndItem, 0, 0)); setLine(line); }
Item * Arrow::endItem() { return myEndItem; }
Item * Arrow::startItem() { return myStartItem; } void Arrow::setName(Text * name) { myName = name; }
void Arrow::setTargetRole(Text * targetRole) { myTargetRole = targetRole; }
void Arrow::setSourceRole(Text * sourceRole) { mySourceRole = sourceRole; }
void Arrow::setTargetMult(Text * targetMult) { myTargetMult = targetMult; }
void Arrow::setSourceMult(Text * sourceMult) { mySourceMult = sourceMult; }
void Arrow::setColor(QColor color) { myColor = color; }
void Arrow::setNamePosition(Item *item1, Item *item2) { QPolygonF item1Polygon = item1->shape().toFillPolygon(); QPolygonF item2Polygon = item2->shape().toFillPolygon(); QPointF intersectPoint1; QPointF intersectPoint2; QPointF p1; QPointF p2; QLineF line1 = line(); QLineF line2;
p1 = item1Polygon.first() + item1->pos(); for (int i = 1; i < item1Polygon.count(); i++) { p2 = item1Polygon.at(i) + item1->pos(); line2 = QLineF(p1,p2); if (line1.intersect(line2,&intersectPoint1) == QLineF::BoundedIntersection) break; p1 = p2; }
p1 = item2Polygon.first() + item2->pos(); for (int i = 1; i < item2Polygon.count(); i++) { p2 = item2Polygon.at(i) + item2->pos(); line2 = QLineF(p1,p2); if (line1.intersect(line2,&intersectPoint2) == QLineF::BoundedIntersection) break; p1 = p2; }
QLineF line0 = QLineF(intersectPoint1,intersectPoint2); double x = ( line0.x1() - line0.x2() ) / 2; double y = ( line0.y1() - line0.y2() ) / 2; this->childItems().at(0)->setPos( intersectPoint1 - QPointF(x,y) ); }
void Arrow::setStartItemRMPosition(Item* item) { QLineF line1 = QLineF (item->pos(),item->mapToScene(item->boundingRect().topLeft())); QLineF line2 = QLineF (item->pos(),item->mapToScene(item->boundingRect().topRight()));
double angle1 = line2.angleTo(line1); double angle2 = 180 - angle1;
double angle0 = acos(line().dx() / line().length())*180/Pi;
if (line().dy() < 0) angle0 = 360 - angle0;
if (((angle0 > (360 - angle2/2)) && (angle0 <= 360)) || ((angle0 >= 0) && (angle0 <= angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topLeft()); QPointF p22 = item->mapToScene(item->boundingRect().bottomLeft()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(1)->setPos(intersectPoint1 - QPointF(childItems().at(1)->boundingRect().width(),0)); childItems().at(3)->setPos(childItems().at(1)->mapToScene(childItems().at(1)->boundingRect().bottomLeft())); } if ((angle0 > (angle2/2)) && (angle0 <= (90 + angle1/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topLeft()); QPointF p22 = item->mapToScene(item->boundingRect().topRight()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(1)->setPos(intersectPoint1 - QPointF(0, 2 * childItems().at(1)->boundingRect().height())); childItems().at(3)->setPos(childItems().at(1)->mapToScene(childItems().at(1)->boundingRect().bottomLeft())); } if ((angle0 > 90 + angle1/2) && (angle0 <= (180 + angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topRight()); QPointF p22 = item->mapToScene(item->boundingRect().bottomRight()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(1)->setPos(intersectPoint1); childItems().at(3)->setPos(childItems().at(1)->mapToScene(childItems().at(1)->boundingRect().bottomLeft())); } if ((angle0 > (180 + angle2/2)) && (angle0 <= (360 - angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().bottomRight()); QPointF p22 = item->mapToScene(item->boundingRect().bottomLeft()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(1)->setPos(intersectPoint1); childItems().at(3)->setPos(childItems().at(1)->mapToScene(childItems().at(1)->boundingRect().bottomLeft())); } }
void Arrow::setEndItemRMPosition(Item* item) { QLineF line1 = QLineF (item->pos(),item->mapToScene(item->boundingRect().topLeft())); QLineF line2 = QLineF (item->pos(),item->mapToScene(item->boundingRect().topRight()));
double angle1 = line2.angleTo(line1); double angle2 = 180 - angle1;
double angle0 = acos(line().dx() / line().length())*180/Pi;
if (line().dy() < 0) angle0 = 360 - angle0;
if (((angle0 > (360 - angle2/2)) && (angle0 <= 360)) || ((angle0 >= 0) && (angle0 <= angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topRight()); QPointF p22 = item->mapToScene(item->boundingRect().bottomRight()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(2)->setPos(intersectPoint1); childItems().at(4)->setPos(childItems().at(2)->mapToScene(childItems().at(2)->boundingRect().bottomLeft())); } if ((angle0 > (angle2/2)) && (angle0 <= (90 + angle1/2))) { QPointF p11 = item->mapToScene(item->boundingRect().bottomLeft()); QPointF p22 = item->mapToScene(item->boundingRect().bottomRight()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(2)->setPos(intersectPoint1); childItems().at(4)->setPos(childItems().at(2)->mapToScene(childItems().at(2)->boundingRect().bottomLeft())); } if ((angle0 > 90 + angle1/2) && (angle0 <= (180 + angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topLeft()); QPointF p22 = item->mapToScene(item->boundingRect().bottomLeft()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(2)->setPos(intersectPoint1 - QPointF(childItems().at(2)->boundingRect().width(),0)); childItems().at(4)->setPos(childItems().at(2)->mapToScene(childItems().at(2)->boundingRect().bottomLeft())); } if ((angle0 > (180 + angle2/2)) && (angle0 <= (360 - angle2/2))) { QPointF p11 = item->mapToScene(item->boundingRect().topRight()); QPointF p22 = item->mapToScene(item->boundingRect().topLeft()); QLineF line11 = QLineF(p11,p22); QLineF line22 = this->line(); QPointF intersectPoint1; line11.intersect(line22, &intersectPoint1); childItems().at(2)->setPos(intersectPoint1 - QPointF(0, 2 * childItems().at(2)->boundingRect().height())); childItems().at(4)->setPos(childItems().at(2)->mapToScene(childItems().at(2)->boundingRect().bottomLeft())); } }
/////////////////////////////////////////////////////////// // Item.cpp // Implementation of the Class Item // Created on: 02-июн-2010 20:51:40 ///////////////////////////////////////////////////////////
#include <QtGui>
#include "Item.h"
Item::Item(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsPolygonItem(parent, scene) { myFillColor = Qt::red; setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemIsSelectable, true); }
QPixmap Item::image() const { QPixmap pixmap(250, 250); pixmap.fill(Qt::transparent); QPainter painter(&pixmap);
painter.setPen(QPen(Qt::black,8)); painter.translate(125, 125); painter.drawPolyline(myPolygon);
return pixmap; }
void Item::addArrow(Arrow * arrow) { myArrows.append(arrow); }
void Item::setFillColor(QColor color) { myFillColor = color; setBrush(myFillColor); }
void Item::removeArrow(Arrow * arrow) { int index = myArrows.indexOf(arrow); if (index != -1) myArrows.removeAt(index); }
void Item::removeArrows() { foreach (Arrow *arrow, myArrows) { arrow->startItem()->removeArrow(arrow); //Item.cpp:54: error: invalid use of incomplete type 'struct Arrow' arrow->endItem()->removeArrow(arrow); scene()->removeItem(arrow); delete arrow; } }
QPointF Item::getPosition() { return myPosition; }
void Item::setPosition(QPointF position) { myPosition = position; setPos(myPosition); }
QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemPositionChange) { foreach (Arrow *arrow, myArrows) { arrow->updatePosition(); } }
return value; }
Название: Re: Проблема с #include
Отправлено: BRE от Июня 07, 2010, 20:54
C++ (Qt) /////////////////////////////////////////////////////////// // Item.cpp // Implementation of the Class Item // Created on: 02-июн-2010 20:51:40 /////////////////////////////////////////////////////////// #include <QtGui> #include "Item.h" #include "Arrow.h" // !!!!
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 21:02
ага! спасибо! но как-то нерационально всё: в Item.h писать class Arrow, а потом в Item.cpp всё равно #include "Arrow.h". появились новые ошибки, но с ними, надеюсь, сам справлюсь :)
Название: Re: Проблема с #include
Отправлено: BRE от Июня 07, 2010, 21:03
но как-то нерационально всё: в Item.h писать class Arrow, а потом в Item.cpp всё равно #include "Arrow.h".
Если разобраться как это работает, то получиться рационально. ;)
Название: Re: Проблема с #include
Отправлено: dware от Июня 07, 2010, 21:07
так есть всё-таки почитать чо?)
Название: Re: Проблема с #include
Отправлено: Alex Custov от Июня 07, 2010, 22:31
так есть всё-таки почитать чо?)
любая хорошая книжка по С++, и лучше две.
|