How to Properly Use Namespaces in C++

How do you properly use namespaces in C++?

Namespaces are packages essentially. They can be used like this:

namespace MyNamespace
{
class MyClass
{
};
}

Then in code:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

Or, if you want to always use a specific namespace, you can do this:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

Edit: Following what bernhardrusch has said, I tend not to use the "using namespace x" syntax at all, I usually explicitly specify the namespace when instantiating my objects (i.e. the first example I showed).

And as you asked below, you can use as many namespaces as you like.

Appropriate use of namespace in C++

When you see :: in C++, it doesn't mean namespace. :: is the scope resolution operator. There are different ways to define scope in C++, Namespaces and Classes are two of these ways. Explaining their differences, pros, and cons is outside the scope if your original question.

To answer what you're asking in a more roundabout way, yes, putting functions inside Classes and Namespaces is Good C++. Otherwise, your functions will all wind up in the Global scope. Which makes for very messy programming and defeats much of the design of C++.

However, simply writing Foo::Baz() does not define Foo as a class or namespace either.

To properly use a namespace, one would first declare it and then declare the member functions as such:

namespace MyCoolNamespace {
void aFunction();
void anotherFunction(bool b);
}

And then define the functions like so:

void MyCoolNamespace::aFunction()
{
/* something this function does */
}

It can then be called the way the tutorial mentions (however keep in mind, the tutorial's scope is a class, not a namespace!)

MyCoolNamespace::aFunction();

or called with the assistance of the using the using keyword:

using namespace MyCoolNamespace;

aFunction();

How to use namespaces and classes?

Simply declare it an equivalent1 namespace of the same "name" !

file1.cpp

namespace Example {
int vartest;
void foo();
}

file2.cpp

namespace Example {
int othervar;
void otherfoo();
}

Namespaces are merged.

Do they have to be declared in header files?

No. You can declare any namespace inside a namespace. (Note that the "global scope" is also a namespace)

How do I declare functions in a namespace?

Simply declare it within the namespace. As you have done.

And let's say I am working on a large project with different files.
And I define a namespace in a file, but then want to add more
functions to that same namespace, but those functions are defined in
another file. Can that be done?

Namespaces of the same name, within the same namespace are merged.

namespace X { void foo(){} }
namespace X { void foo(){} } //Error, redefinition of `foo` because the namespace ::X is merged

namespace X { void foo(){} }
namespace Y { void foo(){} } //Ok. Different name spaces...

namespace X { void foo(){} }  // ::X
namespace Y { void foo(){} } // ::Y

namespace Y {
namespace X { // namespace ::Y::X here isn't same as ::X
void foo(){} //OK
}
}

1 recall that the so called "global scope" is actually a namespace known as global namespace

How do you use namespaces?

thats a lot of questions in one question post!

1) Why use Namespaces?
as you stated in the question, they are AN orginizational method for code. there really is no "one way" to orginize code so commonly named objects arn't causing you issues. Creating one class library might use an entirely different mechinism than another library.

2) How should I use namespaces?
I prefer how Microsoft has grouped their namespaces (see 3.5 name space map!). Group by functionality, inheritance, whatever! namespaces are just another orginizational tool to be used. That being said, I err on the side of less is more. as you said, namespaces can obscure code, as well as hide functional code from other developers (which namespace had that gridrow class i needed? Grid or Row?). I try to only use namespaces when the need arizes. Call me sloppy, but it has worked for me so far!

Summary: avoid complexity. don't over categorize your code.

How to properly use namespaces to avoid name collision?

Of course, when I use it, I wouldn't like to type my::vector all the time, so I'd like using namespace my. However, I could eventually need something from the std namespace, and then I want using namespace std at the same time, but this will bring me back to the initial name collision problem.

Yes, it would bring you back to the initial name collision problem. This is why you should use using namespace ...; directives sparingly, and only in source files, never in headers.

Does this mean that even when I use namespaces I should still think about giving non-common names to my types?

No, you shouldn't. Namespaces were invented precisely to avoid this.

Or is using namespace a mistake and I should always type my::vector instead?

You can, if you want to, use the using namespace ...; or using ...; directives until you get conflicts. This means that when you do have conflicts, you'll end up writing "unnatural" code by explicitly quallifying names in some places.

In practice, when you're dealing with short namespace names (i.e. std), you can just type them explicitly all the time. After a week or so, you won't even notice you're typing it anymore.

Namespaces in C

When using namespace prefixes, I normally add macros for the shortened names which can be activated via #define NAMESPACE_SHORT_NAMES before inclusion of the header. A header foobar.h might look like this:

// inclusion guard
#ifndef FOOBAR_H_
#define FOOBAR_H_

// long names
void foobar_some_func(int);
void foobar_other_func();

// short names
#ifdef FOOBAR_SHORT_NAMES
#define some_func(...) foobar_some_func(__VA_ARGS__)
#define other_func(...) foobar_other_func(__VA_ARGS__)
#endif

#endif

If I want to use short names in an including file, I'll do

#define FOOBAR_SHORT_NAMES
#include "foobar.h"

I find this a cleaner and more useful solution than using namespace macros as described by Vinko Vrsalovic (in the comments).

Why are namespaces used?

For small, self-contained projects, there's not much need for namespaces, and you'd never create a namespace for each object or concept in your code.

Larger projects using libraries benefit from being isolated from names introduced by those libraries, as well as some internal organisation to make readability easier.

Similarly, when creating a library, it's a good idea to put its contents into a namespace so as not to cause headaches and conflicts for your users (as you don't know how large their projects will be, and what names they may want to use themselves).

To use an analogy: if you have three books, you don't bother organising them alphabetically. But, once you have a hundred, you might decide to categorise them on your bookshelf for easier reference and mental health.

And, if you now borrow another twenty books from a friend, you'd probably keep those in a separate pile so they're easier to find when you need to give them back.

So, to some degree, this is a case of… you'll know why you need it, when you need it.

C++: Namespaces -- How to use in header and source files correctly?

From a code readability standpoint, it is probably better in my opinion to use the #2 method for this reason:

You can be using multiple namespaces at a time, and any object or function written below that line can belong to any of those namespaces (barring naming conflicts). Wrapping the whole file in a namespace block is more explicit, and allows you to declare new functions and variables that belong to that namespace within the .cpp file as well

Usage of namespaces in c++

It's legal to define namespace members outside of their namespace as long as their name is prefixed with the name of their namespace, and the definition actually occurs in a namespace that encloses it. It can't happen in a namespace that's nested inside the member namespace.

namespace A { void f(); }
void A::f() { } // prefix with "A::"

namespace B { }
void B::f() { } // invalid! not declared in B!

namespace C { void f(); }
namespace D { void C::f() { } } // invalid! D doesn't enclose C

namespace E {
void f();
namespace F {
void E::f() { } // invalid! F is nested inside E!
}
}

It's the same stuff as for class members, where you can also define functions outside of their class, as long as you prefix the names with the name of the class. However as for classes, namespace members must be first declared in their respective namespace before they can be defined outside out it.



Related Topics



Leave a reply



Submit