C++ C++;翻译单位

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

我真的不明白什么是翻译单元以及如何使用未命名的名称空间:

如果我有一个.cpp文件:

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()
,非常感谢您的帮助!