Archived

This topic is now archived and is closed to further replies.

ANSI2000

C++ and name spaces

Recommended Posts

Guest Anonymous Poster
Namespaces are used so you can have two different things with the same name (like classes).

If you included two headers, firstheader.h and secondheader.h, and they both contained classes named CClass you''d get errors because you have 2 classes with the same name. You use namespaces to resolve the ambiguity. I don''t ever use them, though, and can''t really remember how they work.

Share this post


Link to post
Share on other sites
Namespaces are to code, what directories are to a filesystem.
One of thier benefits is name-collision avoidance. They also let you package related classes, structs, enums, typedefs, and constants together.

I got a little carried away using namespace today:
  
namespace MKH
{
namespace Network
{
namespace Socket
{
namespace Protocol
{
template<typename TAddress = IPAddress_v4>
struct RTP
{
typedef TAddress Address;
};
}//namespace Protocol


template<class TProtocol>
class Listener
{
public:
bool Listen(const TProtocol::Address& bind)
{
//...

}
private:
TProtocol m_Protocol;
};
}//namespace Socket

}//namespace Network

}//namespace MKH



  
#include <MKH\Socket.hpp>

//This brings the MKH::Network namespace into the local namespace.

//We do this so we don't have to type MKH::Network::

// in front of everything that needs it.

using namespace MKH::Network;

typedef Socket::Protocols::RTP<> RTP;
Socket::Listener<CRTPTestDlg, RTP > m_rtpServer;
RTP::Address ip;

ip.dwAddress = 0x7f000000;
ip.port = 1110;
m_rtpServer.Listen(ip);


Magmai Kai Holmlor

"Oh, like you've never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Edited by - Magmai Kai Holmlor on December 9, 2001 4:26:54 AM

Share this post


Link to post
Share on other sites
From what I understood! Magmai you went over bord there

I think I would prefere to give my classes unique names.

Plus the fact that if in one cpp file you start using one name space you cant use the other one no? So you would still have to reference the other class with it''s name space??

Share this post


Link to post
Share on other sites
You can just add stuff to the namespace from anywhere:

.h file #1
  
namespace Bob
{

class George
{
};

};


.cpp file #1
  
#include "file1.h"

namespace Bob
{

George::George()
{}

}



.h file #2
  
namespace Bob
{
}


.cpp #2
  
namespace Bob
{
}


And you can just keep adding files.

You can add stuff to the std namespace (or any other) if you really wanted to.

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
A namespace just takes the place of putting a prefix on a class name to make the name unique. It would be excessive if you actually had to specify the namespace. You only have to specify a namespace to resolve a conflict. So as an example you could have:

  
//filea

namespace CompanyName
{
namespace SystemA
{
namespace ProjectA
{
namespace LibraryA
{
class SomeClass;
};
};
};
};
//fileb

namespace CompanyName
{
namespace SystemA
{
namespace ProjectA
{
namespace LibraryB
{
class SomeClass;
};
};
};
};
//filec

namespace CompanyName
{
namespace SystemA
{
namespace ProjectB
{
namespace LibraryA
{
class SomeClass;
};
};
};
};
//filed

namespace CompanyName
{
namespace SystemA
{
namespace ProjectC
{
namespace LibraryC
{
class SomeClass;
};
};
};
};


The fully qualified name of SomeClass in filea is CompanyName::SystemA:rojectA::LibraryA::SomeClass. Very cumbersome, but if there is no conflict you can just refer to it as SomeClass in your code. If you also use fileb in the same program then you have to use LibraryA::SomeClass and LibraryB::SomeClass to specify which one you want. If you also include filec then you need ProjectA::LibraryA::SomeClass, ProjectA::LibraryB::SomeClass or ProjectB::SomeClass. If you include filed as well then you add LibraryC::SomeClass or ProjectC::SomeClass, whichever you prefer. All you have to do is say you are using the namespace and any unresolved name is searched for in that namespace.

One nice thing about namespaces is that the first definition defines it, but subsequent ones extend it. That is differant than how a class behaves. If you did that with a class then you would get a compiler error saying duplicate name. In the example above the namespace CompanyName::SystemA includes all four classes if you include all four files. That lets you do things like set standards that the top namespace for all source developed in house be the company name. The indentation can get nasty. It would be nice if you could fully qualify a namespace and have the compiler generate the intermediate namespaces. Personally I just skip the indentation since I put everything in a single file in a single namespace.

You could get carried away and have a base class of Protocol::Listener and derived classes of IP::Listener. It isn''t really getting carried away as much as it is just a style. It made no differance if you called it IPListener or IP::Listener. One person might complain about typing two more letters while another complains that the parts of the name running together. Either way you had to take a specific action to avoid a name conflict that is basically a fundamental part of the program, i.e. you need to support multiple protocols. I would argue that is a specialize situation and that namespaces are more generally useful. You don''t need an anticipated conflict in names to justify using namespaces.

Share this post


Link to post
Share on other sites
I will probably use them but not like crazy levels like you guys define there... JAVA packages are way more cleaner then this

Share this post


Link to post
Share on other sites
Well maybe both of us can learn something, do tell, how to Java packages work?

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
Java packages works exactly how you explained namespaces to me, exactly like a folder system. I sorta new what namespaces where just wasnt exactly sure how I would want to use them...

Say you have the following java source files...

    
// One source

package Engine.Model

class Object
{}
// Another source

package Engine.GUI

class Object
{}

// Another source

package Engine

// Tell java what packages to use.

import Engine.Model.*; // Tell java to use all classes within the specified package

import Engine.GUI.Object; // Tell java to use the specific object


class MyEngine
{
// Refers to the GUI object

Object myWindow = new Object();

Engine.Model.Object myMesh = new Engine.Model.Object();
}



You literaly have to have the physical folders
Engine
|
|-- MyEngine.java
|
|-- Model
| |
| |--- Object.java
| |
|-- GUI
| |
| |--- Object.java
| |

Now I have never fallen into a situation where 2 packages might have the same classes within, but I would assume you have to reference teh object by the exacte package... I will test it and see what happens.



Edited by - ANSI2000 on December 11, 2001 12:42:53 PM

Share this post


Link to post
Share on other sites
quote:
Original post by ANSI2000
Now I have never fallen into a situation where 2 packages might have the same classes within, but I would assume you have to reference teh object by the exacte package... I will test it and see what happens.



You're assumption is correct. The only real difference between Java packages and C++ namespaces is that in Java, source files are defined in a package (and thus all the classes defined in that source file are members of that package), whereas in C++ you can mix-and-match namespaces inside a single file. Besides that the differences are just syntax.

I also like Java's package protection, where classes, functions, or members are only visible to other entities inside the same package. Good way to get away from the friend keyword.

Does C++ have any sort of similar namespace protection?

"So crucify the ego, before it's far too late. To leave behind this place so negative and blind and cynical, and you will come to find that we are all one mind. Capable of all that's imagined and all conceivable."
- Tool
------------------------------


Edited by - wayfarerx on December 11, 2001 12:58:09 PM

Share this post


Link to post
Share on other sites
An example of what you should most likely do in your program is the following:

  
namespace myprogram
{
class myclass;
}

using namespace myprogram;

int main(int argc, char *argv[])
{
myclass myinstance;
}


There isn''t much benefit to that other than that it gets you in the habit of doing it. You didn''t ask what you should do in your program though. You asked what they are and when/how they should be used. So you got stripped down examples. Certainly it would not make any sense to simply nest a bunch of namespaces to define one class. Generally I divide things up into groups of five to ten. So if the company had five systems and each system had five projects and each project created five libraries and each library had five classes that would be 625 classes. Across an entire company with an I/S staff of a few thousand you could easily get into tens of thousands of classes. Think Microsoft, not you dinking around on a computer at home.

What a namespace does is provide a context. So someone says ram. Do they mean random access memory, a male goat or running something into something else? You need a context. So perhaps you have Computer::RAM, Animal::Ram, Action::Ram. Now the possiblities are reduced considerably. Do you write programs in an environment where the most appropriate name for a class is the same as the most appropriate name for a differant class in a differant context? Apparently not. It doesn''t change what they are and when/how you should use them. It simply means you may have no need for them. Since it only takes four lines of code if you count the brackets I would argue you might as well use them even if you don''t need them. Then perhaps someday you will have an alternative to change a name used in a hundred programs. That alternative would be fully qualifying the name in the one program within which you actually have a problem.

Share this post


Link to post
Share on other sites
quote:
Original post by WayfarerX
Does C++ have any sort of similar namespace protection?

Oh, yes.

In C++, you need to either import an entity from a namespace or import the entire namespace (which may lead to namespace pollution/collisiions, requiring you to prefix entitiy names anyway). If you do not prefix the name or import the entity/namespace, the compiler will not be able to find the function:
#include <iostream>
int main(int argc, char *argv[])
{
cout << "Hellow, world!" << endl; // Error: undefined variable ''cout''
return 0;
}


Many people advise against wantonly importing an entire namespace (as is commonly done with namespace std). Do this instead:
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;

Unfortunately, some constructs are more difficult to laocate and thus more difficult to import (I haven''t bothered to aggressively look for getline, for example, but it''s not under std). This procedure can also be tedious if you import several entities. However, since you can import entities at varying scope, you may wish to import the entire namespace within a restricted scope.

[ GDNet Start Here | GDNet FAQ | MS RTFM | STL | Google ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
Thanks Oluseyi, but that wasn't exactly what I was asking. Java packages work in almost the exactly the same way as you described namespaces (just use "import whatever .*;" instead of "using whatever").

In Java you can do this
    
package wayfarerx.stuff; // Puts this class in the 'wayfarerx.stuff' package


class MyClass
{
public int pubInt; // public, everyone can read/write

protected int proInt; // protected, only this class and sub-classes can read/write

int packInt; // Look wierd (for Java)? This uses package protection, only this

// class and classes in the 'wayfarerx.stuff' package can read/write

private int priInt; // private, only for this class

}


I was wondering if C++ provided a mechanism similar to package protection in Java.

quote:

However, since you can import entities at varying scope, you may wish to import the entire namespace within a restricted scope.



Hmmm, didn't know you could do that. Sweet.

"So crucify the ego, before it's far too late. To leave behind this place so negative and blind and cynical, and you will come to find that we are all one mind. Capable of all that's imagined and all conceivable."
- Tool
------------------------------


Edited by - wayfarerx on December 11, 2001 2:32:35 PM

Share this post


Link to post
Share on other sites
I think anything that is protected in a class can only be used directly by the class itself or sibligns, in C++ that is. No??

Also why int packInt is protected by the package, because by default if you do not specify a keyword: public, protected, private and package; java automatically defaults it to package....

Share this post


Link to post
Share on other sites
You can always use the unnamed namespace, which makes anything declared in it invisible from other files. Just like the ol'' C static keyword. And yes, you can nest it withing other namespaces.


file 1:
=======

namespace FOO
{
namespace
{
int foo() { return 0; }
}

int bar()
{
return foo(); // Can use functions of the unnamed namespace locally
}
}

int myfunc1()
{
return FOO::bar() + FOO::foo(); // still works
}

file 2:

namespace FOO
{
namespace
{
int foo() { return 1; } // ok, no conflict, unnamed namespace
}

int bar() // won''t work: FOO::bar() already exist
{
return foo(); // Can use functions of the unnamed namespace locally
}

int baz() {
return foo(); // Will use the local foo(), returning 1
}
}

int myfunc2()
{
return FOO::baz() + FOO::foo(); // will work, with the local foo();
}

Share this post


Link to post
Share on other sites
There''s no additional protection gained by C++ namespaces, that''s what friend is for

Actually I think I lied. If you declare a variable to be static at a namespace scope, only things in that namespace will know it exist. It''s a bit crduer than Java''s package scope... but that''s what friend is for. It''d be nice if you could distinguish between protected and private friends without using a proxy class.

Actaully, the C++ way would be to allow a public, protected, and private visiblity defintion within a namespace. Public is for all to see, sub-namespaces can see protected, and only that namespace can see it''s private part.

Actually, it''s sooo obivous I wonder if it work that way now....

quote:

syntax error : ''public''


Damn

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
But in reality do we use all these features? I dont think so I think one or 2 nested name spaces would be enough C++ or JAVA (packages)

Share this post


Link to post
Share on other sites
Thanks for the info guys!

"So crucify the ego, before it''s far too late. To leave behind this place so negative and blind and cynical, and you will come to find that we are all one mind. Capable of all that''s imagined and all conceivable."
- Tool
------------------------------

Share this post


Link to post
Share on other sites
quote:

But in reality do we use all these features?


A better question is should we use those features.

.Net makes extensive use of namespaces, as does the Java core, oui?

Is there even such a thing as namespace overkill? How could it be too organized? Well, I guess one namespace per class would be overkill...

My motivation is to make code-compeletion more useful. If you know you need a socket::protocol::<avialable protocols pop-up here&gr and not everything under the sun.

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites