包含在头文件的末尾,是安全/良好的做法吗?

时间:2013-10-22 10:06:19

标签: c++ include

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

无论我包含我的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 个答案:

答案 0 :(得分:5)

根据您的具体示例

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

一般

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分: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