7

我开始用 C++ 编写一个简单的解释器,它的类结构将在下面描述,但我退出并用 Java 重写了这个东西,因为头文件让我很难过。这是 C++ 中显然不允许的基本结构:

main.cpp包含 main 函数,并包含一个我们可以调用 print.h 的类的标头其单个 void 方法在printer.cpp中实现)。现在想象另外两个相同的类。两者都想调用Printer::write_something();,所以我在每个中都包含了printer.h。所以这是我的第一个问题:为什么我可以#include <iostream>一百万次,甚至一个接一个,但我只能包括我的标头一次?(好吧,我想我可以用我的做同样的事情,只要它在同一个文件中。但我可能是错的。)我理解声明和实现/定义之间的区别,但该代码给了我一个类重定义错误。我不明白为什么。这就是让我大吃一惊的事情(可能会告诉你为什么我什么都不明白):我不能只在main.cpp的顶部包含print.h并使用我其他两个类中的类。我知道我可以毫无问题地将printer.h包含在两个类(标题)之一中,但我不明白为什么这与在将类包含在main.cpp之前包含它有什么不同(因为这样做会给出我一个类没有找到错误)。

当我厌倦时,我考虑转向 C,因为我使用的 OOP 无论如何都非常强制,但是除非我将所有内容都写在一个文件中,否则我会遇到同样的问题。了解 C++ 但由于编译问题而无法正确使用它令人沮丧。

如果您能帮我解决这个问题,我将不胜感激。谢谢!

4

3 回答 3

9

为什么我可以#include 一百万次,甚至一个接一个,但我只能包含一次标题?

这可能是因为您的标头没有包含保护

// printer.h file
#ifndef PRINTER_H_
#define PRINTER_H_

 // printer.h code goes here

#endif

请注意,最佳做法是为包含保护定义选择更长的名称,以最大程度地减少两个不同标头可能具有相同标头的可能性。

于 2013-01-23T17:04:03.020 回答
4

大多数头文件应该包含在包含保护中:

#ifndef MY_UNIQUE_INCLUDE_NAME_H
#define MY_UNIQUE_INCLUDE_NAME_H

// All content here.

#endif

这样,编译器在每个翻译单元中只会看到一次标头的内容。

于 2013-01-23T17:04:43.587 回答
0

C/C++ 编译分为编译/翻译单元以生成目标文件。(.o, .obj)

看这里翻译单元的定义

C/C++ 文件中的#include 指令直接等效于同一文件中的简单递归复制粘贴。您可以尝试将其作为实验。

因此,如果同一个翻译单元两次包含相同的标头,编译器会看到某些实体被定义了多次,如果你将它们写在同一个文件中就会发生这种情况。错误输出将完全相同。

语言中没有内置的保护措施可以阻止您执行多个包含,因此您必须为每个 C/C++ 标头编写包含保护或特定的#pragma 样板。

于 2013-01-23T19:17:07.543 回答