4

我正在尝试在Qt. 我需要弄清楚QGraphicsItem我的球与哪种类型的球相撞。例如,如果我的球撞到墙上,球就会弹开,如果它撞到砖块,它必须弹开并破坏砖块。为了找出QGraphicsItem它是什么类型,我认为最好的方法可能是覆盖QGraphicsItem::type()(如果这不是正确的方法,请告诉我!)。

在下面的代码中,brick.h我将“Brick”的类型设置为 3。现在,值 3 看起来很难跟踪。我宁愿用“#define”声明一些东西

#include <QGraphicsItem>

//should this #define be here?
//#define BRICK_SPRITE 3

class Brick : public QGraphicsItem
{
public:
    Brick(const QPixmap& p, QGraphicsScene *scene = 0);
    virtual QRectF boundingRect() const;
    virtual void paint( QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
                        QWidget *widget );

    QPainterPath shape() const;

    enum { Type = 3 }; //enum {Type = BRICK_SPRITE}

    int type() const { return Type; }

private:
    QPixmap pixmap;
};

在哪里放置语句 '#define BRICK_SPRITE 3' 的好位置?我在项目中有几个其他文件。我应该将所有定义放在单独的头文件中吗?

4

2 回答 2

5

为什么不直接使用Type而不是 3? enumc++ 中的 s 可以隐式转换为int

如果您真的想要一个新名称,我建议您使用const int变量而不是#define- 它是类型和命名空间安全的,而预处理器宏则不是。

就像是:

class Brick : public QGraphicsItem
{
  static const int BRICK_SPRITE = 3;
  // rest of the class definition
};

根据我能找到的文档,您使用枚举和覆盖type()的方法确实是首选方法

于 2012-05-15T16:36:06.183 回答
5

如果你想遵循 Qt 的约定,你可以从不将常量命名为全部大写开始......他们不这样做。此外,正如@Atilla 指出的那样,对常量使用预处理器宏不是惯用的 C++。有很多很好的理由,比如能够在调试器中看到值:

C++ - enum vs. const vs. #define

通常情况下,您可以找到一个“拥有”常量有意义的类。当 Qt 真的没有地方放它时,它只是把东西放在命名空间中Qt::

http://doc.qt.io/archives/qt-4.7/qt.html

所以如果你发现拥有这个值没有意义Brick,你可以在你的程序中有一个命名空间来放置这些东西。

我实际上不知道这QGraphicsItem::type()是一个标准的东西......没有遇到过它。您已经在文档中注意到它说自定义用户类型应该从UserType + 1...开始,所以我肯定会遵循该规则。它说只有在您打算使用 时才需要这样做qgraphicsitem_cast(),所以也许我看过的示例并不需要它。

就声明常量的约定而言,Qt 带来的唯一不寻常的事情(我能想到的)是称为 Q_DECLARE_FLAGS 的东西,它在您将标志或标志放在一起的情况下带来了类型安全性:

http://doc.qt.io/archives/qt-4.7/qflags.html

因此,如果您正在执行以下操作:

class Brick : public QGraphicsItem {
public:
    static const int Type = UserType + 1;
    enum BrickFlag {
        DamagesBall = 0x1,
        ContainsCoins = 0x2,
        MultipleHits = 0x4
    };
    Q_DECLARE_FLAGS(BrickFlags, BrickFlag)
}

Q_DECLARE_OPERATORS_FOR_FLAGS(Brick::BrickFlags)

现在您有一个称为 的特殊安全类型Brick::BrickFlags,它不能(例如)与Brick::Type.

于 2012-05-15T17:01:14.860 回答