C++ C++;翻译单位
我真的不明白什么是翻译单元以及如何使用未命名的名称空间: 如果我有一个.cpp文件:C++ C++;翻译单位,c++,namespaces,codeblocks,C++,Namespaces,Codeblocks,我真的不明白什么是翻译单元以及如何使用未命名的名称空间: 如果我有一个.cpp文件: namespace { void extFunction() { std::cout << "Called Unnamed Namespace's function.\n"; } } #include <iostream> #include "ext.cpp" using namespace std; int main() { ext
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}
#include <iostream>
#include "ext.cpp"
using namespace std;
int main()
{
extFunction();
return 0;
}
名称空间
{
void extFunction()
{
std::cout翻译单元基本上是您交给编译器处理的代码块。编译器对其进行处理并为链接器生成目标代码。链接器将来自所有翻译单元的目标代码组合在一起,形成可执行文件。(有时您会看到与此不同的详细信息,例如,当您只有一个翻译单元时,无法看到目标代码的文件。尽管实现细节可能有所不同,但此概念仍然有效。)
因此,通常,.o
(或.obj
)之间存在一对一的对应关系编译和翻译单元时生成的文件。通常,每个代码< >代码> >代码>文件。
当您使用#include
指令时,您告诉编译器将该行替换为包含文件的全部内容。也就是说,提供给编译器的代码块包括原始文件和包含文件中的代码。如果将一个.cpp
文件包含到另一个文件中,则提供给编译器将包含两个.cpp
文件中的代码,破坏.cpp
文件和翻译单元之间的等效性。这通常被认为是一个坏主意
让我们看一个例子。假设您有一个名为ext.cpp
的文件,其中包含以下内容:
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}
#include <iostream>
#include "ext.cpp"
int main()
{
extFunction();
return 0;
}
#include <iostream>
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function in EXT.\n";
}
}
void extPublic()
{
extFunction();
}
如果要编译main.cpp
,编译器要做的第一件事就是预处理main.cpp
。这会修改文件的内容,更改编译器看到的内容。预处理后,编译器将处理的代码块如下所示
[lots of code from the library header named "iostream"]
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}
int main()
{
extFunction();
return 0;
}
我们还提供一个标头(ext.h
),它将声明具有外部链接的函数
void extPublic();
现在转到main.cpp
:
#include <iostream>
#include "ext.h" // <-- Including the header, not the source.
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function in MAIN.\n";
}
}
int main()
{
extFunction();
extPublic();
return 0;
}
#包括
#包含“ext.h”//因为您包含它,所以它是同一个翻译单元。“翻译单元”不是“文件”的同义词。#包含
的意思是“将文件的确切内容复制并粘贴到此位置”。因此,您的main.cpp
被编译时,就像您自己将未命名的命名空间放在那里一样。永远不要包含.cpp
文件。如果您没有包含cpp文件,而是将其编译为项目的一部分,您将无法在main中使用extFunction()
,非常感谢您的帮助!