Xerath
Xerath

Reputation: 1099

calling my namespace with std together from another cpp file

I have a Main.cpp and Example.cpp files.

This might be bad what I did, since I'm new to c++, but here is the code I wrote inside my Example.cpp:

#include <iostream>

namespace example {

    using namespace std;

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

}

So, I came to an idea to call that namespace inside Main.cpp:

#include <iostream>  

using namespace example;

int main() {  
    return 0;                      
}

Now I have a problem to call "example" namespace from another file. Do I need to create a header for that cpp file ?

Upvotes: 0

Views: 1145

Answers (2)

Unda
Unda

Reputation: 1899

Here's how you should do. You should declare your functions which are intended to be included in a namespace in a single header file, and then include it in every cpp file which needs it. The implementations of your "namespaced" functions should be in a single cpp file too. With your example, this should be as followed.

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;
}

Once your example namespace declared and implemented, you can use it as followed :

main.cpp :

#include "example.hh"

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

Note that I don't use the using namespace statement and that's why I need to write example:: before the name of my functions. If you want not to have to write example:: each time, you can write using namespace example but be careful : it doesn't not allow you to ommit the #include "example.hh" preprocessor directive otherwise the compiler will not even know your example namespace exists.

So remember : using namespace doesn't stand for a #include directive.

An explanation about source files and header files.

In the example, you have 3 files : 1 header file (example.hh), and 2 source files (example.cpp, main.cpp). It's common (because useful) to declare namespaces, classes, structures, functions ... in a header file, and include this header file in every source file which needs to use one of thoses previously defined names.

Why ? To allow the compiler to know about those names. Here, to make you executablefile , there are two steps :

  • Step 1 : compile every single source file to a corresponding object file, i.e make an example.o file from your example.cpp file. The example.o file will contain byte code (here, the code of your example::myfunc1 and example::myfunc2 functions) and the main.o the code for the main function.

    These object files are made by a compiler. For example, you make an object file with GCC (G++ for C++) as followed : g++ -c -o example.o example.cpp.

    It's here that the header files are useful. When your example.cpp file is read by GCC, GCC reads the #include "example.hh" statement which tells him to read example.hh too, and that's how GCC can know about your namespace and its functions.

    • For example.cpp, if you had not included your header file, GCC would have read void example::myfunc1() { ... } and you would have thrown an error telling you something like Unknown namespace depending on the compiler you use.
    • For main.cpp, you would have got another error telling you that the namespace was not found.

    What is interesting in the way of doing is that in the compile main.o, the byte code roughly says call myfunc1 from the example namespace, then call myfunc2 from the example namespace but it DOES NOT include the code for these 2 functions in main.o file.

    So when GCC reads the function calls, it does not know their implementation but it knows them from the header file. Roughly, declaring them in the header file and include it in the source files tells GCC something like This namespace and its functions exist, they will be implemented somewhere else.

    So here, you have your 2 corresponding object files : main.o and example.o.

  • Step 2 : take all object files you've just made to link them and make an executable. Again, with GCC : gcc -o exampleExcutable main.o example.o. That's where the magic happens : the linker see that there's a call to example::myfunc1 and example::myfunc2, finds their implementation in example.o, and is able to create your executable file.

Here you get your executable file exampleExecutable, you run it and get your expected output :

$ ./exampleExecutable
func1
func2

To concude, header files are used to declare symbols and to be included in source files. When sources files are compiled, the corresponding object files don't contain the definition of these declared symbols, but they're resolved during link time.

Upvotes: 4

AndersK
AndersK

Reputation: 36082

In order for the compiler/linker to know which function you are referring to it needs the prototype of the functions.

Create a header for your namespace e.g.

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

Then include the header in example.cpp and in your main.cpp

Upvotes: 1

Related Questions