C++:使用命名空间和#include

Jac*_*own 23 c++

在C++中,#include指令有什么区别using namespace?您还将名称空间存储为单独的文件,这些文件的文件扩展名是什么?

Eri*_*ric 36

在C++中,#include用于将文件添加到项目中,同时namespace用于将对象保存在逻辑模块中(命名空间不适用于C)

例如,您可能在文件" vector.h"中有一个矢量类,因此您将其包含在项目中.

vector是大型库(标准库)STD的一部分,因此您可以使用它来访问它

std::vector
Run Code Online (Sandbox Code Playgroud)

但是由于程序员很懒,而且不想写std :: all(标准库有许多非常有用的部分),你可以写

using namespace std
Run Code Online (Sandbox Code Playgroud)

在您的文件的顶部.这将告诉编译器每次看到类型(例如向量)时,也要检查命名空间std,因为定义可能在那里.这样,以下陈述就变得相同了.

std::vector
vector
Run Code Online (Sandbox Code Playgroud)

在vector.h中,你应该看到类似的东西

namespace std
{
   class vector { /* Implementation */ }
}
Run Code Online (Sandbox Code Playgroud)

#include添加文件using namespace也是如此,同时保持代码更清晰,并打包在"有意义"的库中.您可以using namespace在编程时省略,但绝对需要#include


Pet*_*ete 26

为了回答你的问题,我将稍微回顾一下C和C++的一些基础知识.

在编译C/C++时,将源文件编译成实际的可执行文件实际上是两个步骤,即编译和链接.编译步骤一次只接受一个.cpp文件并编译它.其他.cpp文件的内容对编译器不可见.这会生成一个"目标文件"(我不知道为什么会这样称呼它).然后,链接器链接所有目标文件以生成最终的可执行文件.

这在C++,声明和定义中引入了两个重要的概念.声明指定某些东西(变量或函数)将存在于某处.以下是函数Foo()的声明

void Foo();
Run Code Online (Sandbox Code Playgroud)

这意味着我们告诉编译器某个地方会有一个函数Foo(),它不带参数并且不返回任何值.

定义指定了实际执行的功能.这里定义了函数

void Foo() { cout << "Foo!!"; }
Run Code Online (Sandbox Code Playgroud)

让我们定义另一个函数,Bar()

void Bar() {
    Foo();
    cout << "bar";
}
Run Code Online (Sandbox Code Playgroud)

该函数调用函数Foo().如果函数foo之前尚未在同一文件中声明或定义,则无法编译此函数.因此声明本身不产生任何编译代码.他们只需要在那里.

如果函数Foo()没有在此文件中定义,而是在另一个.cpp文件中定义,则链接器的作用是在这两个函数之间建立连接.如果函数Foo()没有在任何地方定义,则会出现链接器错误,而不是编译器错误.

这涉及头文件的概念.头文件是存储声明的位置.当使用#include包含头文件的内容时,实际发生的事情是预处理器(在实际编译器之前执行的步骤)将加载包含的文件并将内容"粘贴"到原始源文件中.因此,编译器将看到该文件,就好像整个头文件实际上已粘贴到c ++文件中一样.

因此,当您使用C++编程时,通常会将定义放在.cpp文件中,并将声明放在.h文件中

另一方面,命名空间只是一种逻辑分组代码的方法.

所以不,名称空间不存储在单独的文件中,并且它们没有特定的文件扩展名.如果我有一个具有多个命名空间的项目,我可能会为每个命名空间创建一个单独的目录(然后,我可能不会,它将取决于具体情况).