包含 .cpp 和 #ifndef 而不是 .h 被认为是不好的做法?
include .cpp with #ifndef instead of .h considered bad practice?
这个问题有很多类似的答案,比如这个:
- Include .cpp instead of header(.h)
- (这个回答真的说不好)
堆栈溢出可能会说我有一个重复的问题,但在查看了所有类似的问题后我仍然不明白为什么人们不鼓励使用此代码:
#ifndef _FOO
#define _FOO
// my comment that I only have to write once
int some_method()
{
return 1;
}
#endif
称之为 foo.cpp
。为什么在排除 foo.h
的情况下做这样的事情是不好的做法?编译时间会变慢,但要慢多少?我相信它会慢几毫秒。为什么懒惰是一件坏事 ()。我只想写一些有用的东西,有据可查的等等。
我在使用此技术时看到的好处是:
我不用再写评论了。如果我决定更改函数的注释,我还必须更改头文件中的注释。
如果我更改方法的签名,那么我也必须在头文件中更改它。
我经常在 visual studio 上使用 F12 快捷键来定义一个方法。 Visual studio 默认情况下会转到头文件。我想进入实际实施。看到代码加注释比只看注释对我来说更好。
我看到的唯一不利方面是 。但这比必须将所有内容都写两次要省事。仅包含一些内容,仅此而已。
编辑
我知道我可能错了,我遗漏了什么。因为我是一名 C# 开发人员,所以我很难理解它。我只是不明白为什么这个文件会被包含多次。是的,它会被包含多次,但只有第一次会被编译。其他时候编译不正确?
include .cpp with #ifndef instead of .h considered bad practice?
是的,包括 .cpp 文件被认为是一种不好的做法。
int some_method()
{
return 1;
}
Header 文件经常包含在多个翻译单元中。如果您将该文件包含到多个 TU 中,则您已在多个 TU 中定义了 some_method
。这违反了单一定义规则,您的程序将是 ill-formed.
即使您小指承诺将该文件完全包含到另一个 TU 中,.cpp 文件也会按常规编译 - 可能会根据构建系统自动编译 - 在这种情况下 foo.cpp 文件将是一个 TU 并且包括文件将是另一个 TU,您最终会得到多个定义。
- I do not have to write comments twice.
即使不包含 .cpp 文件,也不需要写两次注释。
- If I change the signature of a method then I will also have to change it on the header file.
这是一个可以自动执行的微不足道的更改。
#define _FOO
该标识符保留给语言实现。您应该使用另一个宏作为 header 守卫。
您永远不应该 #include
.cpp 文件,因为 .cpp 扩展名告诉人们文件是单独编译的翻译单元。它在技术上没有任何问题,但它会误导其他程序员并且会使您的代码混乱且难以维护。
如果您将问题中文件的文件扩展名更改为 .h 或 .hpp,那么只要将其标记为 inline
,就可以将函数的完整定义包含在头文件中。
也就是说,如果您有一个名为“foo.hpp”且包含以下内容的文件,那完全没问题。
#ifndef FOO_HPP_
#define FOO_HPP_
// my comment that I only have to write once
inline int some_method()
{
return 1;
}
#endif
这 会 在大型项目中将编译时间减慢 not-insignificant 数量。将所有(或大部分)代码编译为一个巨大的编译单元总体上比编译 200 个单独的编译单元花费的时间更少,但每次你在任何地方进行更改时都需要 re-compiling。这就是存在单独的编译单元来解决的问题。如果您对代码的一部分进行更改,您希望避免 re-compiling 不相关的代码。在大型项目中,这可以节省相当多的时间。我从事的项目需要一个多小时才能完全完成 re-compile,每次我进行更改时都必须这样做真的很痛苦。
这个问题有很多类似的答案,比如这个:
- Include .cpp instead of header(.h)
- (这个回答真的说不好)
堆栈溢出可能会说我有一个重复的问题,但在查看了所有类似的问题后我仍然不明白为什么人们不鼓励使用此代码:
#ifndef _FOO
#define _FOO
// my comment that I only have to write once
int some_method()
{
return 1;
}
#endif
称之为 foo.cpp
。为什么在排除 foo.h
的情况下做这样的事情是不好的做法?编译时间会变慢,但要慢多少?我相信它会慢几毫秒。为什么懒惰是一件坏事 ()。我只想写一些有用的东西,有据可查的等等。
我在使用此技术时看到的好处是:
我不用再写评论了。如果我决定更改函数的注释,我还必须更改头文件中的注释。
如果我更改方法的签名,那么我也必须在头文件中更改它。
我经常在 visual studio 上使用 F12 快捷键来定义一个方法。 Visual studio 默认情况下会转到头文件。我想进入实际实施。看到代码加注释比只看注释对我来说更好。
我看到的唯一不利方面是 。但这比必须将所有内容都写两次要省事。仅包含一些内容,仅此而已。
编辑
我知道我可能错了,我遗漏了什么。因为我是一名 C# 开发人员,所以我很难理解它。我只是不明白为什么这个文件会被包含多次。是的,它会被包含多次,但只有第一次会被编译。其他时候编译不正确?
include .cpp with #ifndef instead of .h considered bad practice?
是的,包括 .cpp 文件被认为是一种不好的做法。
int some_method() { return 1; }
Header 文件经常包含在多个翻译单元中。如果您将该文件包含到多个 TU 中,则您已在多个 TU 中定义了 some_method
。这违反了单一定义规则,您的程序将是 ill-formed.
即使您小指承诺将该文件完全包含到另一个 TU 中,.cpp 文件也会按常规编译 - 可能会根据构建系统自动编译 - 在这种情况下 foo.cpp 文件将是一个 TU 并且包括文件将是另一个 TU,您最终会得到多个定义。
- I do not have to write comments twice.
即使不包含 .cpp 文件,也不需要写两次注释。
- If I change the signature of a method then I will also have to change it on the header file.
这是一个可以自动执行的微不足道的更改。
#define _FOO
该标识符保留给语言实现。您应该使用另一个宏作为 header 守卫。
您永远不应该 #include
.cpp 文件,因为 .cpp 扩展名告诉人们文件是单独编译的翻译单元。它在技术上没有任何问题,但它会误导其他程序员并且会使您的代码混乱且难以维护。
如果您将问题中文件的文件扩展名更改为 .h 或 .hpp,那么只要将其标记为 inline
,就可以将函数的完整定义包含在头文件中。
也就是说,如果您有一个名为“foo.hpp”且包含以下内容的文件,那完全没问题。
#ifndef FOO_HPP_
#define FOO_HPP_
// my comment that I only have to write once
inline int some_method()
{
return 1;
}
#endif
这 会 在大型项目中将编译时间减慢 not-insignificant 数量。将所有(或大部分)代码编译为一个巨大的编译单元总体上比编译 200 个单独的编译单元花费的时间更少,但每次你在任何地方进行更改时都需要 re-compiling。这就是存在单独的编译单元来解决的问题。如果您对代码的一部分进行更改,您希望避免 re-compiling 不相关的代码。在大型项目中,这可以节省相当多的时间。我从事的项目需要一个多小时才能完全完成 re-compile,每次我进行更改时都必须这样做真的很痛苦。