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

Mat*_*hai 4 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;
};
Run Code Online (Sandbox Code Playgroud)

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

Att*_*ila 5

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

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

就像是:

class Brick : public QGraphicsItem
{
  static const int BRICK_SPRITE = 3;
  // rest of the class definition
};
Run Code Online (Sandbox Code Playgroud)

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


Hos*_*ork 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,它可以在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)
Run Code Online (Sandbox Code Playgroud)

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