繁体   English   中英

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

[英]calling my namespace with std together from another cpp file

我有一个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;                      
}

现在,我有一个问题要从另一个文件调用“示例”命名空间。 我需要为该cpp文件创建头吗?

这是您应该做的。 您应该在单个头文件中声明要包含在名称空间中的函数,然后将其包含在每个需要它的cpp文件中。 您的“命名空间”功能的实现也应该在单个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函数的代码。

    这些目标文件由编译器生成。 例如,使用GCC(C ++为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但是在main.o 包含这两个函数的代码main.o文件。

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

    因此,这里有两个对应的目标文件: main.oexample.o

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

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

$ ./exampleExecutable
func1
func2

总而言之,头文件用于声明符号并包含在源文件中。 编译源文件时,相应的目标文件不包含这些声明的符号的定义,但在链接期间将对其进行解析。

为了使编译器/链接器知道您所指的功能,需要功能原型。

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

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

然后将头文件包含在example.cpp和main.cpp中

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM