0

I am familiar with the following use of namespaces.

In the header file (for example people.h) I describe interface of a name space. For example:

namespace people{
   int getAge(str Name);
   void setName(str Name);
}

Then in people.cpp I define the methods from the space name:

#include "people.h"
int people::getAge(str Name) {
   something_1;
   something_2;
}

void people::setName(str Name) {
   something_1;
}

However, in a header file that I have I see that in addition to the namespace people there are also interfaces of other namespaces (for example namespace dogs). And these name spaces are not defined in the people.cpp file.

So, I assumed that (because of some strange reason) the interface for the namespace dogs is put into the people.h and then then the name space dog is defined in the "dogs.cpp" file. So, in other words I assumed that two different name spaces are defined in two different cpp files but their interface is described in one header file. However, this assumption seems to be wrong because I found that there are many header files that declare "namespace dogs".

So, I assume that namespace dogs in the 2people.h" file has another function but I cannot figure out what function it is. Could anybody please help me with that?

ADDED

The code that I try to understand is written not by me and it works fine. So, it should make sense. May be I was not clear enough. So, I try to give an example:

In the header file (people.h) I have:

namespace etet
{
    class date;
}

namespace xsystem{
    class estimation_module;
}

namespace people {
   a_lot_of_different_stuff;
}

Then the people.cpp defines all the methods that belong to the people name space.

Roman
  • 124,451
  • 167
  • 349
  • 456

2 Answers2

2

You're confusing namespaces and classes. Typically, a class definition occurs in a header file (.h) and the implementation of its member functions appear in the corresponding implementation file (.cpp).

A namespace works differently to a class. If a class is defined in multiple translation units, it must have precisely the same tokens in all of them. You can't even reorder members, even if it would result in the exact same class. It's easy to meet this requirement by using the above described header files. Each translation unit that needs a class foo contains the contents of foo.h because they do #include "foo.h" when they need it. Of course they all contain precisely the same definition of foo bceause they all included foo.h.

However, this is very different to namespaces. A namespace can be introduced multiple times across the same and different translation units without it being the same tokens every time. Something like this is totally fine:

namespace bar {
  void baz();
  struct x;
}
// some stuff
namespace bar {
  void do_something(x);
}

Each occurence of namespace bar introduces some declarations to that namespace.

You will often have many classes defined in the same namespace. Each header for those classes will do namespace whatever { ... } and introduce the class definition into that namespace.

Sometimes you will even want to introduce things to multiple namespaces or nested namespaces in a single header file. There's nothing to stop you doing that. A possible situation for doing that is if you want to forward declare something from another namespace. Let's say you have a class defined in people.h like so:

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}

Now, this class needs to know about the type dog in the dogs namespace. One way to do his would be to #include "dogs.h". However, since pet_dog is only a pointer, we can do with an incomplete type, so we can forward declare dog like so:

namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • I know the difference between the classes and name spaces. I just say that in the header file I see a declaration of a name space that contains descriptions of all methods belonging to the name space (i.e. for every method its return type and type of variables is given). Then in the corresponding cpp file all these methods are defined/coded (in the cpp it is defined what these methods do). I am fine with all that. What i do not understand, why in the header file we need declaration of other name spaces (that contain descriptions of interfaces of its methods). – Roman Feb 26 '13 at 14:00
  • @Roman I've added an example to the end of why this might occur. It's probably what you're seeing. – Joseph Mansfield Feb 26 '13 at 14:03
  • thank you. Now it is more clear. We have declarations of other name spaces in the `people.h` because we want to use "members" (classes or methods or variables) from these name spaces. What remains unclear to me, is why we cannot just include the headers of these name spaces (then we can use any members of these name spaces). – Roman Feb 26 '13 at 14:10
  • 1
    @Roman The same reason we use forward declaration without namespaces. Including headers introduces dependencies and increase compilation times. If all you need is a forward declaration of a certain class, there's no point including the entire header file. – Joseph Mansfield Feb 26 '13 at 14:12
  • but how the compiler know what `namespace dogs`. It knows that we want to use a particular member of a particular name space, but how does it know in what `.h` ir `.cpp` file the `namespace dog` is declared? – Roman Feb 26 '13 at 14:19
  • 1
    @Roman: the compiler does not need to know where the classes of the `dogs` namespace are actually defined, this is the whole point of forward declaration. A forward declaration only tells the compiler that some type exists, without precising its content. When you actually need to know the content of these types, then you would include the appropriate header. If you look into `people.cpp`, you should probably see some `#include` directives for `etet::date` and `xsystem::estimation_module`, because the implementation file (the `.cpp`) needs the full definition of these types. – Luc Touraille Feb 26 '13 at 14:37
  • Finally, the compiler does not need to know where the functions are implemented (i.e. in which `.cpp`): this is the job of the linker to take all the object files generated from the `.cpp` and merge them in a single executable/library (this is called separate compilation). To understand the difference between declaration and definition, see [this question](http://stackoverflow.com/q/1410563/20984); about forward declaration, see [these](http://stackoverflow.com/q/9906402/20984) [questions](http://stackoverflow.com/q/553682/20984). – Luc Touraille Feb 26 '13 at 14:46
2

The "namespace interface" is a misleading concept. A namespace is just a bounch of names grouped together under a surname (like you and your brothers and sisters). It has no "interface" because there is no namespace "obejct".

The

#include "people.h"
int people::getAge(str Name) {
   something_1;
   something_2;
}

void people::setName(str Name) {
   something_1;
}

is perfectly equivalent to

#include "people.h"
namespace people
{
  int getAge(str Name) {
     something_1;
     something_2;
  }

  void setName(str Name) {
     something_1;
  }
}

may be this is more familiar, or may be not. The fact an header declares functions not present in a cpp, just means they are probably present in another one.

About the fact that the namespace name { ..... } declaration can be repeated in many files, each containing various function is perfectly normal, since the namespace keyword does not declare an object. It just group names. And -in fact- sayning a namespace is "declared" is a common language abuse. What is declared is the name of the namespace.

And different names declare in different places can belong to a same group. there is nothing mysterious in that.

You lexicon makes me thinking you are confusing namespaces with classes and structs

ADDED:

After your clarification, it looks like the a_lot_of_different_stuff contains declarations that use etet::date and xsystem::estimation_module;

This names (and only the names) must be known to the compiler, but the header cannot recursively include ther respective headers because they most likely already included people.h.

A typical "curculare reference" problem, like in here, but involving different namespaces.

Community
  • 1
  • 1
Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
  • you are right. `a_lot_of_different_stuff` use `etet::date` and `xsystem::estimation_module`. So, I assume it is why the corresponding nane spaces are present in the header file. But I am not completely understand why we cannot include headers of these two name space (`etet` and `xsystem`). Do I get you right, you say that we cannot include the headers of these two name spaces because these two headers already include `people.h` so, we can get a "cyclic" inclusion? – Roman Feb 26 '13 at 14:06
  • @Roman: Yes, that's My hypotesys. But it can also be that those headers can be wery long and all what people.h needed was just those two names, hence they replicated the forward declarations. You can find a similar behavior in the standard library: think to the `` header: it contains the forward declaration of the classes defined in ``, for all the cases only names are needed, without all the details. – Emilio Garavaglia Feb 28 '13 at 07:32