优点 &将所有代码放在 C++ 的头文件中的缺点? [英] Pros & Cons of putting all code in Header files in C++?

查看:29
本文介绍了优点 &将所有代码放在 C++ 的头文件中的缺点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以构建一个 C++ 程序,以便(几乎)所有代码都驻留在头文件中.它本质上看起来像一个 C# 或 Java 程序.但是,您确实需要至少一个 .cpp 文件来在编译时拉入所有头文件.现在我知道有些人会绝对讨厌这个想法.但我没有发现这样做的任何令人信服的缺点.我可以列出一些优点:

You can structure a C++ program so that (almost) all the code resides in Header files. It essentially looks like a C# or Java program. However, you do need at least one .cpp file to pull in all the header files when compiling. Now I know some people would absolutely detest this idea. But I haven't found any convincing downsides of doing this. I can list some advantages:

[1] 更快的编译时间.所有头文件只被解析一次,因为只有一个 .cpp 文件.此外,一个头文件不能被多次包含,否则你会得到一个构建中断.使用替代方法时,还有其他方法可以实现更快的编译,但这很简单.

[1] Faster compile times. All header files only get parsed once, because there is only one .cpp file. Also, one header file cannot be included more than once, otherwise you will get a build break. There are other ways of achieving faster compiles when using the alternate approach, but this is so simple.

[2] 它通过使它们绝对清晰来避免循环依赖.如果 ClassA.h 中的 ClassA 循环依赖于 ClassB.h 中的 ClassB,我必须放一个前向参考它突出.(请注意,这与 C# 和 Java 不同,在 C# 和 Java 中编译器会自动解决循环依赖.这会鼓励 IMO 错误的编码实践).同样,如果您的代码在 .cpp 文件中,您可以避免循环依赖,但在实际项目中,.cpp 文件往往包含随机标头,直到您可以't 弄清楚谁取决于谁.

[2] It avoids circular dependencies, by making them absolutely clear. If ClassA in ClassA.h has a circular dependency on ClassB in ClassB.h, I have to put a forward reference & it sticks out. (Note that this is unlike C# & Java where the compiler automatically resolves circular dependencies. This encourages bad coding practices IMO). Again, you can avoid circular dependencies if your code was in .cpp files, but in a real-world project, .cpp files tend to include random headers until you can't figure out who depends on whom.

你的想法?

推荐答案

原因 [1] 更快的编译时间

不在我的项目中:源文件 (CPP) 仅包含它们需要的头文件 (HPP).所以当我因为一个微小的变化而只需要重新编译一个 CPP 时,我有十倍相同数量的文件没有被重新编译.

Reason [1] Faster compile times

Not in my projects: source files (CPP) only include the headers (HPP) they need. So when I need to recompile only one CPP because of a tiny change, I have ten times the same number of files that are not recompiled.

也许您应该在更符合逻辑的源代码/标头中分解您的项目:对 A 类实现的修改不应该需要重新编译 B、C、D、E 等类的实现.

Perhaps you should break down your project in more logical sources/headers: A modification in class A's implementation should NOT need the recompilation of implementations of class B, C, D, E, etc..

代码中的循环依赖?

抱歉,我还没有遇到过这种问题是真正的问题:假设 A 依赖于 B,而 B 依赖于 A:

Sorry, but I have yet to have this kind of problem being a real problem: Let's say A depends on B, and B depends on A:

struct A
{
   B * b ;
   void doSomethingWithB() ;
} ;

struct B
{
   A * a ;
   void doSomethingWithA() ;
} ;

void A::doSomethingWithB() { /* etc. */ }
void B::doSomethingWithA() { /* etc. */ }

解决该问题的一个好方法是将这个源至少分解为每个类一个源/头(以类似于 Java 的方式,但每个类有一个源和一个头):

A good way to resolve the problem would be to break down this source into at least one source/header per class (in a way similar to the Java way, but with one source and one header per class):

// A.hpp

struct B ;

struct A
{
   B * b ;
   void doSomethingWithB() ;
} ;

.

// B.hpp

struct A ;

struct B
{
   A * a ;
   void doSomethingWithA() ;
} ;

.

// A.cpp
#include "A.hpp"
#include "B.hpp"

void A::doSomethingWithB() { /* etc. */ }

.

// B.cpp
#include "B.hpp"
#include "A.hpp"

void B::doSomethingWithA() { /* etc. */ }

因此,没有依赖性问题,并且编译时间仍然很快.

Thus, no dependency problem, and still fast compile times.

我错过了什么吗?

在实际项目中,cpp 文件往往包含随机标题,直到您无法弄清楚谁取决于谁

in a real-world project, cpp files tend to include random headers until you can't figure out who depends on whom

当然.但是,如果您有时间重新组织这些文件以构建您的一个 CPP"解决方案,那么您就有时间清理这些标题.我的标题规则是:

Of course. But then if you have time to reorganize those files to build your "one CPP" solution, then you have time to clean those headers. My rules for headers are:

  • 分解标题以使其尽可能模块化
  • 永远不要包含不需要的标题
  • 如果您需要一个符号,请提前声明它
  • 仅当上述操作失败时,才包含标题

无论如何,所有的headers都必须是自给自足的,这意味着:

Anyway, all headers must be self-sufficient, which means:

  • 标题包括所有需要的标题(并且只有需要的标题 - 见上文)
  • 必须编译包含一个头文件的空 CPP 文件,而无需包含任何其他内容

这将消除排序问题和循环依赖.

This will remove ordering problems and circular dependencies.

如果编译时间真的是一个问题,我会考虑:

Should compile time be really an issue, I would consider either:

您所做的不是将所有内容都放在标题中.

What you are doing is not putting everything in headers.

您基本上是将所有文件都包含在一个且只有一个最终来源中.

You are basically including all your files into one and only one final source.

也许您在完整项目编译方面获胜.

Perhaps you are winning in terms of full-project compilation.

但是当编译一个小的变化时,你总是会失败.

But when compiling for one small change, you'll always lose.

在编码时,我知道我经常编译小的更改(如果只是为了让编译器验证我的代码),然后最后一次,做一个完整的项目更改.

When coding, I know I compile often small changes (if only to have the compiler validate my code), and then one final time, do a full project change.

如果我的项目按照您的方式组织,我会浪费很多时间.

这篇关于优点 &将所有代码放在 C++ 的头文件中的缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆