为什么.cpp文件和.h文件之间有区别? [英] Why is there a difference between a .cpp file and a .h file?

查看:64
本文介绍了为什么.cpp文件和.h文件之间有区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Microsoft Visual Studio.为什么在以下代码中包含.h文件时却不能访问变量?

I'm using Microsoft Visual Studio. Why can I access the variable when I include a .h file and not when I include a .cpp file in the following code?

file.h

int i = 10;

file.cpp

int i = 10;

main.cpp包括.h

main.cpp including .h

#include <iostream>
#include "file.h"

int main()
{
     std::cout << i << std::endl;     // ok: output: 10
     return 0;
}

main.cpp包括.cpp

main.cpp including .cpp

#include <iostream>
#include "file.cpp"

int main()
{
     std::cout << i << std::endl;     // error: LNK1169, LNK2005
     return 0;
}

推荐答案

这里有两件事.

包含文件时,将在编译器开始编译之前将包含的文件粘贴到包含文件中.这意味着将在main.cpp中有一个file.cpp的完整副本,该副本将被编译.

When you include a file, the included file is pasted into the including file before the compiler begins compiling. This means there is a complete copy of file.cpp in main.cpp that will be compiled.

接下来,Visual Studio要编译cpp文件.可以看到file.cpp是项目的一部分,对其进行编译,然后将其与main.cpp的编译输出链接以创建可执行程序.

Next, Visual Studio wants to compile cpp files. It sees file.cpp is part of the project, compiles it, and links it with the compiled output of main.cpp to make an executable program.

链接器现在必须处理两个具有自己的 int i 的文件(可能是link.obj和main.obj).链接器放弃并打印出多定义错误消息.它甚至没有试图找出哪一个是正确的,因为只有程序员的意图才能使一个比另一个正确.您将不得不等待将来的C ++标准中对心灵感应式编译器的支持,以解决这些问题.在那之前不要这样做.

The linker now has to deal with two files (probably link.obj and main.obj) that have their own int i. The linker gives up and prints out a multiple definition error message. It doesn't even try to figure out which one is correct because only the intentions of the programmer makes one more correct than the other. You will have to wait for telepathic compiler support in a future C++ standard to sort that mess out. Until then don't do it.

请注意我之前写的关于将包含文件复制到包含文件中的内容.这意味着即使在file.h中定义了 int i ,您也不会遇到麻烦.

Note what I wrote earlier about the included file being copied into the including. This means even with int i being defined in file.h you aren't out of trouble.

如果main.cpp和future.cpp都包含file.h,则您将再次拥有两个带有 int i 的文件.包含保护在这里无济于事,因为它们只会阻止在一个编译文件中重复头(翻译单元).

If main.cpp and future.cpp both include file.h, you once again have two files with int i. Include guards will not help here because they only stop a header from being duplicated within one compiled file (a translation unit).

解决方案是不要在标头中定义标识符,除非您采取措施使它们唯一,或者告诉编译器它们不是唯一的标识符.强烈建议不要在替代方法中定义标识符.

The solution to this is don't define identifiers in headers unless you take steps to make them unique or tell the compiler that it's OK that they aren't. Strongly prefer not defining the identifier to the alternatives.

对于作为变量的标识符,请使用 extern 关键字通知编译器 i 或任何其他变量,但是将分配给其他位置.然后,您需要在其他位置恰好定义一个变量.例如:

For an identifier that is a variable use the extern keyword to inform the compiler that i, or any other variable exists, but will be allocated elsewhere. You are then required to define the variable in exactly one elsewhere. eg:

file.h

extern int i;

file.cpp

int i = 0;

现在main.cpp或任何其他文件都可以包含file.h并使用 i .他们所有人都使用相同的 i ,因此请小心使用.要非常非常小心.通常,有更好的方法可以在多个翻译单元之间共享变量,因此请花一些时间来寻找其他解决方案.调试时间到了,您很可能会感谢您自己.

Now main.cpp or any other file can include file.h and use i. All of them are using the same i, so be careful with it. Be very, very careful. There is very often a better way to share a variable across multiple translation units, so spend the time looking for a different solution. You will most likely thank yourself when debugging time comes.

另一种方法是将变量定义为 static

An alternative is to define the variable as static

file.h

static int i;

使用 static 时,每个包含文件.h的文件都有其自己的 i ,仅在包含文件中可见.链接器不再参与.这几乎总是一个坏主意.如果必须定义一些变量以支持头文件,则真正头需要的类是一个很好的选择.

When using static every file that includes file .h has it's own i that is only visible within the including file. The linker is no longer involved. This is also almost always a bad idea. If you have variables that must be defined to support a header file, odds are good what the header really needs is a class.

对于作为函数的标识符,请使用 inline 关键字.

这篇关于为什么.cpp文件和.h文件之间有区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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