从另一个cpp文件中使用std调用我的命名空间

时间:2014-06-24 11:38:25

标签: c++ namespaces

我有一个Main.cpp和Example.cpp文件。

这可能是我做的很糟糕,因为我是c ++的新手,但这里是我在Example.cpp中写的代码:

#include <iostream>

namespace example {

    using namespace std;

    void myfunc1() {
        cout << "func1" << endl;
    }
    void myfunc2() {
        cout << "func2" << endl;
    }

}

所以,我想到了在Main.cpp中调用该命名空间:

#include <iostream>  

using namespace example;

int main() {  
    return 0;                      
}

现在我有一个问题要打电话&#34;示例&#34;另一个文件的命名空间我是否需要为该cpp文件创建标题?

2 个答案:

答案 0 :(得分:3)

这是你应该怎么做的。您应该在单个头文件中声明要包含在命名空间中的函数,然后将其包含在需要它的每个cpp文件中。 您的&#34;命名空间&#34;的实现函数也应该在一个cpp文件中。 在您的示例中,这应该如下。

example.hh:

#ifndef  __EXAMPLE_HH__
# define __EXAMPLE_HH__

namespace example
{
   void myfunc1();
   void myfunc2();
}

#endif

example.cpp:

#include <iostream>
#include "example.hh"

void example::myfunc1()
{
    std::cout << "func1" << std::endl;
}

void example::myfunc2()
{
    std::cout << "func2" << std::endl;
}

声明并实现您的示例命名空间后,您可以按照以下方式使用它:

main.cpp:

#include "example.hh"

int main()
{
    example::myfunc1();
    example::myfunc2();
    return (0);
}

请注意,我没有使用using namespace语句,这就是为什么我需要在我的函数名称之前写example::的原因。 如果您不想每次都写example::,可以编写using namespace example但要小心:它不允许您省略#include "example.hh"预处理程序指令,否则编译器甚至不知道你的example名称空间存在。

请记住:using namespace并不代表#include指令。

关于源文件和头文件的说明。

在该示例中,您有3个文件:1个头文件(example.hh)和2个源文件(example.cpp,main.cpp)。 在头文件中声明命名空间,类,结构,函数...是常见的(因为有用),并在每个源文件中包含此头文件需要使用之前定义的名称之一。

为什么?允许编译器知道这些名称。在这里,为了使您成为可执行文件,有两个步骤:

  • 步骤1:将每个源文件编译为相应的目标文件,即从example.o文件中生成example.cpp文件。 example.o文件将包含字节代码(此处为example::myfunc1example::myfunc2函数的代码)和main.o main函数的代码。< / p>

    这些目标文件由编译器生成。例如,您使用GCC(G ++ for C ++)创建一个目标文件,如下所示:g++ -c -o example.o example.cpp

    这里的头文件很有用。当GCC读取您的example.cpp文件时,GCC会读取#include "example.hh"语句,告诉他也要阅读example.hh,以及GCC如何了解您的命名空间及其功能

    • 对于example.cpp,如果您没有包含头文件,GCC会读取void example::myfunc1() { ... }并且根据您使用的编译器,您会抛出错误告诉您类似Unknown namespace的内容
    • 对于main.cpp,您可能会收到另一个错误,告诉您找不到命名空间。

    有趣的是,在编译main.o中,字节代码粗略地表示call myfunc1 from the example namespace, then call myfunc2 from the example namespace,但 DOES NOT 包含这两个函数的代码在main.o档案中。

    因此,当GCC读取函数调用时,它不知道它们的实现,但它从头文件中知道它们。粗略地说,在头文件中声明它们并将其包含在源文件中告诉GCC类似This namespace and its functions exist, they will be implemented somewhere else

    所以在这里,你有2个相应的目标文件:main.oexample.o

  • 第2步:获取您刚刚创建的所有目标文件以链接它们并生成可执行文件。再次,GCC:gcc -o exampleExcutable main.o example.o。魔术发生的地方:链接器看到有example::myfunc1example::myfunc2的调用,在example.o找到它们的实现,并且能够创建你的可执行文件文件

在这里,您可以获得可执行文件exampleExecutable,然后运行它并获得预期的输出:

$ ./exampleExecutable
func1
func2

要实现,头文件用于声明符号并包含在源文件中。编译源文件时,相应的目标文件不包含这些声明符号的定义,但它们会在链接时解析。

答案 1 :(得分:1)

为了让编译器/链接器知道你所指的是哪个函数,它需要函数的原型。

为您的名称空间创建标题,例如

#ifndef EXAMPLE_H
#define EXAMPLE_H
namespace example
{
  void myfunc1();
  void myfunc2();
};
#endif

然后在example.cpp和main.cpp

中包含标题