C ++预编译的头文件和包含的文件组织

时间:2014-11-12 19:05:13

标签: c++ c++11 visual-studio-2013 native

我有一个非常大的Native C ++项目,其中有数百个类,每个类都在自己的.cpp和.h文件中定义。这里没什么奇怪的。我在我的预编译头stdafx.h文件中声明了所有类,并且还包含在stdafx.h文件中,如下所示(允许Foo引用Bar AND Bar引用Foo)。

这个组织是不好的做法吗?

基本上,所有类都被声明并包含在每个对象中。我假设编译器不会通过包含不需要编译特定.cpp对象文件的内容来生成开销二进制文件。截至目前,我对编译时间也没有任何问题。我只是想知道这是否是一个糟糕的代码组织。

我喜欢这种布局,因为stdafx.h文件基本上是一个代码映射,因为所有类都在那里声明,它揭示了嵌套的命名空间是一种易于阅读的格式。这也意味着我的单个.h文件不需要多个include语句,这意味着在更改文件名或目录时我需要维护更少的代码。

stdafx.h中:

#pragma once
namespace MyProject
{
    class Foo;
    class Bar;
}

#include "Foo.h"
#include "Bar.h"

foo.h中:

#pragma once

namespace MyProject
{
    class Foo
    {
        // Declare class members, methods, etc
    }
}

Foo.cpp中:

#include "stdafx.h"

namespace MyProject
{
    class Foo
    {
        // Define class members, methods, etc
    }
}

2 个答案:

答案 0 :(得分:2)

在我看来,这里有4个关键因素:

  1. 编译时间:请记住,#include "x.h"将x.h中的所有代码嵌入到该行中。如果项目要大幅增长,那就要关心你将如何影响未来的编译时间。
  2. FooBar稳定性:如果FooBar正在发生变化,您将不得不继续重新编译stdafx.h
  3. 循环定义:您将无法再使用前向声明来破坏循环定义。
  4. 显式依赖关系:您无法查看包含内容并了解特定文件中使用的内容。
  5. 如果你觉得你的专业人士超过了这里列出的缺点,那么你所做的事情并不违法,所以去吧!

答案 1 :(得分:0)

  1. 标题应包含所需的一切,不多也不少 这是易用性和简单封装的基本要求。

    您的示例明确地失败了。

    要检测违规行为,请始终在翻译单元中首先包含相应的标题 如果您使用预编译的标头,则会稍微修改一下,在这种情况下,必须首先包含它们。

  2. 预编译的标题应该只包含很少更改的元素。

    对预编译头或其依赖项的任何更改都将强制重新编译所有内容,这与使用一个内容完全相反。

    你的例子也失败了。

  3. 总而言之,要改进很多。