1

我一直在尝试编写自己的状态机,其中每个状态都是从状态基类派生的单独类。

无论我在哪里包含我的 state_t 类文件(#include“state_t.h”),我都希望包含所有派生的状态类头文件,因此我不必每次需要使用状态机时都单独包含它们或创建一个新的状态。

因为直到 state_t.h 结束才定义“state_t”,所以我只能在文件 state_t.h 的末尾包含我的状态文件。我以前从未编写过这样做的代码,这似乎有点奇怪!我可以添加一个将所有文件收集在一起的顶级“statemachine.h”,但这似乎是一种浪费。

我的问题是:这样做是否正确/安全/可以?任何缺点/问题?

注意:目前我的代码都是测试代码,并且是用 Qt 编写的,但它应该是一个直接的 c++ 问题。

这是我的基类(state_t.h) -注意最后的#include :

#ifndef STATE_T_H
#define STATE_T_H

#include <QByteArray>
#include <QDebug>

class state_t
{
public:
    state_t(QByteArray stateName);
    virtual ~state_t();
    virtual state_t * processState(int input) = 0;
    QByteArray getState();

    QByteArray name;
};

#include "teststate1.h"
#include "teststate2.h"

#endif // STATE_T_H

这是一个状态派生类(teststate1.h):

#ifndef TESTSTATE1_H
#define TESTSTATE1_H

#include "state_t.h"

class testState1 : public state_t
{
public:
    testState1();
    state_t *processState(int input);
};

#endif // TESTSTATE1_H

这是我的 main.cpp:

#include <QCoreApplication>
#include <QDebug>
#include "state_t.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    state_t *myState = new testState1();

    myState = myState->processState(1);
    myState = myState->processState(2);
    myState = myState->processState(3);
    myState = myState->processState(1);

    return a.exec();
}

注意:代码一切正常,这真的是一个“正确性”的问题。

4

4 回答 4

5

鉴于您的特定示例

这是个坏主意。您在错误的方向上引入了基类型和派生类型之间的非常紧密的耦合。基类应该对它的派生类型一无所知。这是使它成为有效基类的原因之一。在您当前的方案中,每次编写派生类型时,您都必须触及基类的标头,从而强制编译时依赖于基类的所有客户端代码。除此之外,您还有一个循环包含依赖项。

一般来说

在非病理情况下,这取决于情况。关于头文件,有人可能会争辩说最好知道文件需要哪些头文件,在这种情况下,将它们放在顶部是有意义的。但是,如果包含被认为是只会分散注意力的实现细节,则可以将它们放在底部。以我的经验,这特别适用于模板代码的实现,以及匿名命名空间中帮助类和内联函数的实现。

于 2013-10-22T10:14:23.890 回答
4

就个人而言,我更愿意将所有包含在顶部。您可以在其他标题中使用前向声明来解决定义顺序问题。

但这只是一种风格——明智的“正确性”,你没有理由不能这样做。你可以在任何你喜欢的地方有效地包含任何东西,这很可能会在以后引起混乱!

于 2013-10-22T10:09:43.480 回答
1

我更喜欢将我的包含放在顶部,否则可能会有点混乱。我对你的建议是不要在 test_t.h 中包含 teststate1.h 和 teststate2.h 而是创建 state_all.h

#include "state_t.h"
#include "teststate1.h"
#include "teststate2.h"

并在需要的地方包含 state_all.h 而不是 state_t.h

于 2013-10-22T11:25:09.923 回答
1

根据我的说法,这只是一个约定,因为每个人都这样做,如果他需要添加一些标准开发人员不会查看文件的末尾,这将是一些包含在顶部和一些的混乱在底部。

于 2013-10-22T10:10:28.840 回答