C++ Namespaces, comparison to Java packages

Viewed 31032

I've done a bunch of Java coding recently and have got used to very specific package naming systems, with deep nesting e.g. com.company.project.db. This works fine in Java, AS3/Flex and C#. I've seen the same paradigm applied in C++ too, but I've also heard that it's bad to view C++ namespaces as direct counterparts to Java packages.

Is that true, and why? How are namespaces/packages alike and different? What problems are likely to be seen if you do use deep nested namespaces?

6 Answers

In C++ namespaces are just about partitioning the available names. Java packages are about modules. The naming hierarchy is just one aspect of it.

There's nothing wrong, per-se, with deeply nested namespaces in C++, except that they're not normally necessary as there's no module system behind them, and the extra layers just add noise. It's usually sufficient to have one or two levels of namespace, with the odd extra level for internal details (often just called Details).

There are also extra rules to C++ namespaces that may catch you out if overused - such as argument-dependent-lookup, and the rules around resolving to parent levels. WRT the latter, take:

namespace a{ namespace b{ int x; } }
namespace b{ string x; }
namespace a
{
  b::x = 42;
}

Is this legal? Is it obvious what's happening? You need to know the precendence of the namespace resolution to answer those questions.

Java packages are not nested, they're flat. Any apparent nesting is nothing more than a naming convention.

For example, the package com.company.project.db has no relation whatsoever to com.company.project or com.company.project.db.x. Code in com.company.project.db has no more access to code in com.company.project.db.x than would code in a.b.c.

You can have nested namespaces in C++.

They don't work the same as in java, though, obviously. Java packages are really much better defined and there is no real static init weirdness. With C++ namespaces are helpful but still have a fair bit of danger involved.

In C++, the basic unit of design and implementation is the class, not the namespace. Namespaces were intended as a means of preventing name clashes in large libraries, not for expressing concepts.

Classes have several advantages over namespaces:

  • they can have constructors and destructors
  • they can have private members
  • they cannot be re-opened

However, I would look twice at any deeply nested relationship. That is really not a good way of designing software, and leads to unreadable code, whether you juse classes or namespaces.

I think there is something missing in the previous answers, and it is one of the reasons I really like C++.

Imagine you are programming a graphical application and suddenly you realize that there is something common among all your widgets. You want all of them to have a new function. What do you do?

1) Edit the base widget class? OK, but most likely you do not have access to it. Maybe there is a licensing problem that prevents you from doing your own modification. Even if you can just do it, if it is something that only makes sense for your project, the authors will not include it in their future release, and upgrading the toolkit will be more painful

2) Create an interface class / multi-inheritance? Depending on your existing code it will be more or less of a pain to update every single class related with a widget. Do this and your code will cost more to maintain because everyone defining a new class must know that they are suppose to inherit from your interface. Becoming dependent of other people discipline is really risky.

The wonderful thing of C++ namespaces here is that you have an extra way to encapsulate stuff within an already existing system. Not only you can encapsulate within already existing libraries that you cannot edit, you can encapsulate similar concepts that you cannot easily insert into your hierarchy of classes/objects.

Java forces you to focus more on a pure OOP design. Sure that I am telling you might be a dirty hack and not elegant, but there are lots of lazy people programming who do not spend time fixing their designs.

Related