有充分的理由在h文件中使用include保护而不是cpp文件吗



例如,从我对C++和clang++的基本理解来看,我不明白为什么以下设置不可取:

使用带有头的变体似乎会产生更多的输出,需要更具体的编译器设置,并且在函数声明中需要双重性。

clang++ --std=c++2a Start.cpp -o Start.o; ./Start.o

启动.cpp

#include "A.cpp"
#include "B.cpp"
int main (
int argc,
char** argv
) {
A();
B();
return 0;
}

A.cpp

#ifndef A_H
#define A_H
#include <stdio.h>
#include "C.cpp"
void A() {
printf("An");
C();
}
#endif

B.cpp

#ifndef B_H
#define B_H
#include <stdio.h>
#include "C.cpp"
void B() {
printf("Bn");
C();
}
#endif

C.cpp

#ifndef C_H
#define C_H
#include <stdio.h>
void C() {
printf("Cn");
}
#endif

如果将该对象文件与包含一个cpp文件的另一个对象文件链接,则程序将违反一个定义规则,因为这些文件包含非内联函数的定义。

此外,编译cpp文件并将它们链接在一起也是常规做法。如果您都编译了这些cpp文件中的任何一个,同时还将其包含到另一个翻译单元中,那么您将遇到违反ODR的情况。

为了解决这个问题,如果将一个文件包含到其他文件中,则通常应确保包含的文件(即头文件(在包含到多个翻译单元中时不包含任何会违反ODR的内容。

此外,最好遵循常用的命名方案。对头文件使用cpp扩展名与所有常见的命名方案相反。

有充分的理由在h文件中使用include保护而不是cpp文件吗?

无论如何命名头文件,都应始终在所有头文件中使用include-guard。(尽管从技术上讲,有些收割台不需要收割台护罩,但简单地使用收割台护罩比跟踪是否需要更容易(。


现在,如果你想知道是否可以将所有的函数定义放在一个翻译单元中:是的,你可以。这有优点也有缺点:

单一TU的优点:由于不重复编译模板和其他内联函数,从头开始的编译时间更快。还有更好的优化,因为没有阻止优化的翻译单元边界-这种优势因跨TU边界工作的链路时间优化而减弱。

缺点:对程序的任何更改都只会导致修改后的翻译单元重新编译。当整个程序只有一个翻译单元时,任何更改,无论多么小,都需要重新编译整个程序。这是非常不可取的。这种缺点通过链接时间优化而减少,链接时间优化会导致链接太慢,以至于从重复使用的翻译单元节省的时间可能变得微不足道。

最新更新