将#.npp包含.cpp而不是.h视为不好的做法?

时间:2020-09-02 17:02:11

标签: c++ header

对此问题有很多类似的答案,例如:

  1. Include .cpp instead of header(.h)
  2. https://stackoverflow.com/a/1001723/637142(此答案确实表明是不好的)

堆栈溢出很可能会说我有一个重复的问题,但是在研究了所有类似的问题后,为什么人们不鼓励使用此代码,我仍然不明白:

#ifndef _FOO
#define _FOO

// my comment that I only have to write once
int some_method()
{
    return 1;
}

#endif

将此称为foo.cpp。为什么在排除foo.h的情况下做这样的事情是不好的做法?编译时间会慢一些,但是会慢多少?我相信它将慢几毫秒。为什么懒惰是一件坏事(https://stackoverflow.com/a/9253825/637142)。我只想写一些行之有效的文档,等等。

使用此技术时看到的好处是:

  1. 我不必写两次评论。如果我决定更改函数的注释,则还必须更改头文件上的注释。

  2. 如果更改方法的签名,则还必须在头文件中对其进行更改。

  3. 例如,我在Visual Studio上经常使用F12快捷键来定义方法。默认情况下,Visual Studio将转到头文件。我想去实际的实现。对我来说,看到代码加注释比看到注释更好。

我看到的唯一不利的一面是https://stackoverflow.com/a/1001667/637142。但这比写两次所有内容要少。只是其中的几个而已。

编辑

我知道我可能错了,我缺少了一些东西。由于我是C#开发人员,因此我很难理解它。我只是不明白为什么会多次包含此文件。是的,它将被多次包含,但是只有第一次会被编译。其他时候它不会被编译正确吗?

2 个答案:

答案 0 :(得分:3)

用#ifndef而不是.h包括.cpp被认为是不好的做法吗?

是的,包括.cpp文件被认为是不好的做法。

int some_method()
{
    return 1;
}

头文件通常包含在多个翻译单元中。如果将文件包含在多个TU中,则您已在多个TU中定义了some_method。这违反了“一个定义规则”,您的程序格式不正确。

即使您小指承诺将该文件准确地包含到另一个TU中,也通常会编译.cpp文件-可能会根据构建系统自动进行编译-在这种情况下,foo.cpp文件将是一个TU,而包含文件将是另一个TU TU,您最终会有多个定义。

  1. 我不必写两次评论。

即使您不包括.cpp文件,也无需两次编写注释。

  1. 如果更改方法的签名,则还必须在头文件中更改它。

这是可以自动进行的微不足道的更改。


#define _FOO

该标识符保留给语言实现。您应该使用另一个宏作为标题保护。

答案 1 :(得分:3)

永远不要{。{1}} .cpp文件,因为.cpp扩展名告诉人们文件是一个单独编译的翻译单元。没什么技术上的错误,但它会误导其他程序员,并使您的代码混乱且难以维护。

如果将问题中文件的文件扩展名更改为.h或.hpp,则可以将函数的整个定义包含在头文件中,只要您将其标记为#include

也就是说,如果您有一个名为“ foo.hpp”的文件,且具有以下内容,那就完全可以了。

inline

在大型项目中,此的编译速度大大降低了。将全部(或大部分)代码作为一个庞大的编译单元进行编译,比编译200个单独的编译单元所需的时间更少,但是每次在任何地方进行更改时,都需要重新编译所有代码。那就是存在单独的编译单元要解决的问题。如果对代码的一部分进行更改,则要避免重新编译不相关的代码。在大型项目中,这可以节省大量时间。我从事的项目需要一个多小时才能完全重新编译,而每次进行更改时都必须这样做,这确实很痛苦。