C ++ / Qt编码风格 - #define定义在哪里

时间:2012-05-15 16:32:06

标签: c++ qt constants qgraphicsitem

我正在尝试在Qt中构建一个分组游戏克隆。我需要弄清楚我的球与QGraphicsItem碰撞的类型。例如,如果我将球与墙碰撞,球就会反弹,如果它与砖碰撞,它必须反弹并摧毁砖。要找出它是什么类型QGraphicsItem,我认为最好的方法是覆盖QGraphicsItem::type()(如果这不是正确的方法,请告诉我!)。

brick.h的以下代码中,我将'Brick'设置为Type 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'的好位置在哪里?我在项目中有几个其他文件。我应该将所有定义放在单独的头文件中吗?

2 个答案:

答案 0 :(得分:5)

为什么不使用Type而不是3? c ++中的enum可以隐式转换为int

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

类似的东西:

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

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

答案 1 :(得分: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()是标准的事情......没有遇到过它。您已经注意到in the documentation它说自定义用户类型应该从UserType + 1开始......所以我肯定会遵循该规则。它说如果你打算使用qgraphicsitem_cast(),你只需要这样做,所以也许我看过的例子不需要它。

Qt在声明常量的约定方面给表(我能想到的)带来的唯一不寻常的东西叫做Q_DECLARE_FLAGS,它可以在OR标记的情况下带来类型安全性:

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一起进行OR运算。

相关问题