C++ 在头文件中存储代码是否会导致C++;?

C++ 在头文件中存储代码是否会导致C++;?,c++,memory-management,header-files,C++,Memory Management,Header Files,不久前,一个人告诉我,将所有代码存储在.h文件中会产生一些内存管理问题。因为一个类的副本太多了。如果我将代码存储在.h/.cpp文件中,就可以避免这个问题。这是真的吗 我已经在谷歌上搜索了一些关于这个主题的信息,我读到这都是关于习惯的。那么,如果将所有代码存储在.h文件中,内存问题又会怎样呢 。。。一个人告诉我,将所有代码存储在.h文件中会产生一些内存管理问题。[…]如果我将代码存储在.h/.cpp文件中,就可以避免这个问题。这是真的吗 内存管理通常指在运行时处理动态内存。为了清楚起见:在标题中

不久前,一个人告诉我,将所有代码存储在.h文件中会产生一些内存管理问题。因为一个类的副本太多了。如果我将代码存储在.h/.cpp文件中,就可以避免这个问题。这是真的吗

我已经在谷歌上搜索了一些关于这个主题的信息,我读到这都是关于习惯的。那么,如果将所有代码存储在.h文件中,内存问题又会怎样呢

。。。一个人告诉我,将所有代码存储在.h文件中会产生一些内存管理问题。[…]如果我将代码存储在.h/.cpp文件中,就可以避免这个问题。这是真的吗

内存管理通常指在运行时处理动态内存。为了清楚起见:在标题中编写所有代码与此无关。但是,这样做可能会增加编译器实际使用的内存量。因此,如果这是一个人的意思,那么是的,这可能是真的-但这不是该方法的最大问题

因为我一个类的副本太多了

这是一个愚蠢的论点。事实上,对定义只使用头文件意味着只有一个翻译单元,其中类定义只包含一次

潜在的问题是,您的单个翻译单元包含所有头文件中的所有定义。由于所有内容都是一次性处理的,因此编译器所需的最大内存可能更高。对于大多数项目来说,这可能无关紧要,但对于libreoffice这样的项目来说,这可能会成为一个问题


在标题中定义所有函数(即使用单个翻译单元)的一个更大的问题是,对任何标题的任何更改,无论多么小,都会导致单个大规模翻译单元发生更改,并且需要重新编译它。对于多个较小的翻译单元,只有受更改影响的单元需要重新编译

因此,您的方法的问题是,每次重新编译都像从头开始编译一样慢。当然,如果编译只需要一分钟,那也没关系,但是对于需要几个小时从头编译的项目来说,这是至关重要的。

你的“一个人”不知道他在说什么

使用头文件只能(潜在地)导致编译器(或实现编译阶段的程序)在编译期间消耗更多内存。这取决于编译器是如何实现的。一个高质量的编译器会处理这个问题。如果某个编译单元有足够的代码导致编译器内存不足,那么这就是另一个问题。。。。而且基本上与头文件的使用无关

如果您编写的代码在您的程序中引起内存管理问题,那么将该代码放入头文件并没有什么区别——坏代码将导致程序产生内存管理问题(泄漏、使用悬空指针等),而不管该代码的部分是否在头文件中

如果不小心使用了头文件,则在某些情况下,多个目标文件可能各自包含某些函数的定义。从技术上讲,这可能会增加程序的内存使用,但也有一些编码技术可以缓解这种情况——尽管如果使用头文件,这些技术的一些细节可能会略有不同。换句话说,造成差异的是编写糟糕的代码,而不是(自己)将代码放入头文件

头文件(或更一般的预处理器)的使用还有其他问题。但是,使用头文件和管理这些问题的技术也有好处。不管怎样,这些问题实际上与内存管理问题无关


实际上,通常最好在头文件和编译单元(aka.h和.cpp文件)之间合理地分割代码。但也有一些情况下,将库的函数定义放在头文件中是有益的(例如模板库)。

请说什么?我不明白你在问什么。没有内存问题,但有一个名称污染问题,你没有可用的编译器防火墙。这反过来意味着循环模块关系存在问题。有了编译器防火墙,a的实现可以依赖于B的接口,反之亦然,将它们作为单独的模块,但对于纯头模块,您必须以某种方式对其进行篡改。好吧,如果您尝试两次包含头中的某些代码,这可能会导致一些问题,这就是为什么您应该使用include-guard。但除了在这方面没有其他问题。例如,很多boost库都是只包含头的,我认为“太多重复项”指的是内联函数——在不同的转换单元中有许多它们的副本,链接器应该扔掉这些副本(除了一个)。所以,关于“只包含一次类定义的一个翻译单元”的部分是错误的-恰恰相反-因为类定义包含在许多翻译单元中,所以有所有这些相同的内联函数,应该注意。@anatolyg如果所有代码都在头中,那么这些不同的翻译单位是从哪里来的呢?对不起,我误解了。我从来没有完全在头文件中使用过代码,只有一个翻译单元。