Nested namespaces

R

Rubén Campos

Organizing classes, types, structures, enums and whatever other entities
into nested namespaces requires to include into every header and
implementation file the complete path of namespaces. Let me show an example:
classes.hpp classes.cpp util.hpp util.cpp main.cpp

// classes.hpp
namespace Classes
{
class MyBaseClass
{
public:
virtual void Print ( ) = 0;
};

class MyDerivedClass
{
public:
virtual void Print ( );
};
}

// classes.cpp
#include "classes.h"
#include <iostream>

using std::cout;
using std::endl;

namespace Classes
{
void MyDerivedClass::print ( ) { cout << "MyDerivedClass::print()" <<
endl; }
}

// util.hpp
namespace Util
{
#include "classes.h"

using Classes::MyBaseClass;
using Classes::MyDerivedClass;

class MyUtilClass : public MyBaseClass
{
public:
void Print ( );
};
}

// util.cpp
#include "util.h"
#include <iostream>

using std::cout;
using std::endl;

namespace Util
{
void MyUtilClass::print () { cout << "MyUtilClass::print()" << endl; }
}

// main.cpp
#include "util.h"

int main (int argn, char ** argv)
{
Util::MyDerivedClass object;

object.Print();

return 0;
}

Linker returns an unresolved external: "virtual void
Util::Classes::MyDerivedClass::print(void)". The reason is that Util
namespace includes MyDerivedClass declaration, but not its definition. ¿Is
there any way to include only the last namespace, while keeping namespace
nested? Thank you very much in advance.
 
V

Victor Bazarov

Rubén Campos said:
Organizing classes, types, structures, enums and whatever other entities
into nested namespaces requires to include into every header and
implementation file the complete path of namespaces. Let me show an example:
classes.hpp classes.cpp util.hpp util.cpp main.cpp

// classes.hpp
namespace Classes
{
class MyBaseClass
{
public:
virtual void Print ( ) = 0;
};

class MyDerivedClass

Probably

class MyDerivedClass : public MyBaseClass
{
public:
virtual void Print ( );
};
}

// classes.cpp
#include "classes.h"
#include <iostream>

using std::cout;
using std::endl;

namespace Classes
{
void MyDerivedClass::print ( ) { cout << "MyDerivedClass::print()" <<
endl; }
}

// util.hpp
namespace Util
{
#include "classes.h"

This is A BAD IDEA(tm). No 'include' directive should appear inside
a namespace. Are you trying to work around some bug or name clash or
something similar? If not, move the 'include' directive outside the
namespace.
using Classes::MyBaseClass;
using Classes::MyDerivedClass;

class MyUtilClass : public MyBaseClass
{
public:
void Print ( );
};
}

// util.cpp
#include "util.h"
#include <iostream>

using std::cout;
using std::endl;

namespace Util
{
void MyUtilClass::print () { cout << "MyUtilClass::print()" << endl; }
}

// main.cpp
#include "util.h"

int main (int argn, char ** argv)
{
Util::MyDerivedClass object;

object.Print();

return 0;
}

Linker returns an unresolved external: "virtual void
Util::Classes::MyDerivedClass::print(void)". The reason is that Util
namespace includes MyDerivedClass declaration, but not its definition.

That's a BAD IDEA(tm).
¿Is
there any way to include only the last namespace, while keeping namespace
nested? Thank you very much in advance.

I don't understand the question. The 'MyDerivedClass' is declared and
defined in its own namespace, "::Classes" (note the leading double colon).
If you want to move it into the namespace "::Util::Classes", you have to
move both the declaration and the definition.

What "last namespace" are you talking about? What do you mean by a "way
to include" a namespace? Include where? 'using' declarations are a way
to include a namespace into the set of searched namespaces, but that has
nothing to do with what you did. You essentially defined two different
namespaces in two different translation units. That's why you get your
symbol unresolved.

V
 
R

Rubén Campos

Victor Bazarov said:
Probably

class MyDerivedClass : public MyBaseClass

Yes, I forgot to include the base class.
This is A BAD IDEA(tm). No 'include' directive should appear inside
a namespace. Are you trying to work around some bug or name clash or
something similar? If not, move the 'include' directive outside the
namespace.

I think this is a bad idea, too. It's better to move the #include out of the
namespace.
That's a BAD IDEA(tm).


I don't understand the question. The 'MyDerivedClass' is declared and
defined in its own namespace, "::Classes" (note the leading double colon).
If you want to move it into the namespace "::Util::Classes", you have to
move both the declaration and the definition.

What "last namespace" are you talking about? What do you mean by a "way
to include" a namespace? Include where? 'using' declarations are a way
to include a namespace into the set of searched namespaces, but that has
nothing to do with what you did. You essentially defined two different
namespaces in two different translation units. That's why you get your
symbol unresolved.

V

Ok, I'll try to explain better the question.

I know that my example is not correct, and I know why it is not correct. But
I included it in my message to illustrate what I was asking for.

I'm not referring to use members of a namespace, which is a thing I have no
problem with. I'm looking for a way to effectively move a namespace (or its
members, if you prefer) inside another, nesting those namespaces. In order
to do this in my example, you're right when saying that I have to move both
the declaration and the definition.

The obvious way to do this, again as you say, is declaring and defining
MyBaseClass and MyDerivedClass into ::Util::Classes. I know. But this imply
to include Util namespace name in classes.hpp and classes.cpp files; if Util
namespaces changes in the future, I'll to modify those files, although
MyBaseClass and MyDerivedClass does not belong directly to Util namespace,
but to a nested one, and although Classes namespace has not changed at all.

It's a maintenance question. I asked for a way (if it's possible) to refer
only the namespace that directly contains a class (or other entity), and not
all the path from the global namespace ('::').

I hope this will clear my question. Sorry if you find it a trivial or
non-sense question. Again, thank you very much for your help.
 
M

Malte Starostik

Rubén Campos wrote:

[example of #include inside a namespace]
The obvious way to do this, again as you say, is declaring and defining
MyBaseClass and MyDerivedClass into ::Util::Classes. I know. But this imply
to include Util namespace name in classes.hpp and classes.cpp files; if Util
namespaces changes in the future, I'll to modify those files, although
MyBaseClass and MyDerivedClass does not belong directly to Util namespace,
but to a nested one, and although Classes namespace has not changed at all.

Unlinke structs and classes, namespaces are extensible, i.e. you can
always add declarations to it:

classes.hpp:

namespace Util
{
namespace Classes
{
class MyBaseClass { /* ... */ };
}
}

util.hpp:

#include "classes.hpp"

namespace Util
{
class MyUtilClass : public Classes::MyBaseClass { /* ... */ };
}

is perfectly valid.
It's a maintenance question. I asked for a way (if it's possible) to refer
only the namespace that directly contains a class (or other entity), and not
all the path from the global namespace ('::').

I'm not entirely sure what you mean by this, maybe like I used
Classes::MyBaseClass instead of ::Util::Classes::MyBaseClass in
MyUtilClass's base clause above?
I hope this will clear my question. Sorry if you find it a trivial or
non-sense question. Again, thank you very much for your help.

I hope I understood your question correctly and the above wasn't
completely missing the point.

Regards,
Malte

PS: Your newsreader includes your real name unencoded in 8 bit in the
From: header, which is invalid and resulted in my automatic quote prefix
being "Rub����������������������������������������" schrieb:
Please check if you can configure it to correctly encode the accented é.
Your header: From: "Rubén Campos" <...>
One possible correct encoding: From: =?ISO-8859-1?Q?Rub=E9n_Campos?= <...>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Infinite loop problem 1
dynamic_cast and generic pointer 9
Pseudocode 1
Cannot find my infinite loop 1
How to keep count of right answer and wrong answers in C++? 0
polymorphism 5
Namespaces 7
I need help 1

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top