9
\$\begingroup\$

I know that nested namespaces are used in C++ very rarely. But I think it's a nice solution to exclude types from global scope and sometimes it helps to write programs faster when we use things like "IntelliSense" or search for documentation (maybe it's similar for C# developers).

I've tried to organize my simple 3D graphics engine library in this way. Here is its main header file:

#ifndef RAZOR_H
#define RAZOR_H

#pragma warning (disable: 4482)

#include <Windows.h>
#include <fstream>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <map>

#include <gl\GL.h>
#include "Externals\wglext.h"
#include "Externals\gl3.h"

namespace Razor
{
    namespace Framework
    {   
        #include "DisplayOrientation.h"
        #include "ButtonState.h" 
        #include "GameTime.h"
        #include "Rect.h"
        #include "Point.h"
        #include "Color.h"
        #include "Vector2.h"
        #include "Vector3.h"
        #include "Vector4.h"
        #include "Matrix.h"

        #include "GameWindow.h"
        #include "Game.h"

        namespace IO
        {
            #include "File.h"
        }

        namespace Input
        {   
            #include "ButtonState.h"
            #include "MouseState.h"
            #include "Keyboard.h"
            #include "Mouse.h"
            #include "TouchPanel.h"
        }

        namespace Graphics
        {
            #include "PrimitiveType.h"
            #include "VertexElementFormat.h"
            #include "VertexElementUsage.h"
            #include "VertexElement.h"
            #include "VertexDeclaration.h"
            #include "OpenGLExtensions.h"
            #include "DepthFormat.h"
            #include "BufferUsage.h"
            #include "PresentationParameters.h"
            #include "RenderTarget.h"
            #include "OpenGLVersion.h"
            #include "Viewport.h"
            #include "Shader.h"
            #include "VertexShader.h"
            #include "FragmentShader.h"
            #include "GeometryShader.h"
            #include "ShaderContainer.h"
            #include "VertexBuffer.h"
            #include "GraphicsDevice.h"
            #include "VertexBuffer.h"
            #include "GraphicsDeviceManager.h"
        }
    }
}

#endif // RAZOR_H

What kind of problems can I get in the future if I organize my library in this way? Do you think this is really a bad style of coding?

\$\endgroup\$
15
\$\begingroup\$

I don't think there is anything inherently wrong with nested namespaces.

I also disagree that it is rare. It is just not exposed directly.

std::tr1
CompanyName::ProductName
CompanyName::ProductName::Details

But like all features they can be abused so use judiciously. But saying that I see nothing wrong with your namespace hierarchy. BUT the way you are implementing it is a very bad idea.

If I include the file "File.h" I expect everything included to be declared in the correct namespace. But the way you define it, it is now possible to include it in a way that puts the classes in the wrong namespace.

Each header file should be designed so that it can not be used incorrectly.

\$\endgroup\$
  • \$\begingroup\$ +1 for that last line. Make your code as robust as possible, down to minute details. \$\endgroup\$ – Maxpm Oct 18 '11 at 20:54
2
\$\begingroup\$

It's better, much more better to protect (you eventually protect) your names in the file scope, where they are declared. So, your using of namespaces protects names only in include scope, and what if I will try to include some of your headers and forget to frame it with a namespace? How will I even know what namespace to use?

This topic correlates with header guards (which you use correctly here). Rule #24 from "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices":

Always write internal #include guards. Never write external #include guards

BTW, very good book.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the nice commment. I didn't think of this issue in the beginning. it hadn't been supposed that I could've include headers from razor.h separably. Indeed I wanted to reduce #include directives in my code by including the only one razor.h file and then using only needed namespaces. \$\endgroup\$ – shadeglare Aug 16 '11 at 10:20
2
\$\begingroup\$

There's nothing inherently wrong with nested namespaces, but note that namespaces are (in my opinion, and as far as I have read) intended to prevent name clashes, not to organise code. They are not rare -- there's boost, for example, which has plenty of nested namespaces, but as far as I've seen, they are usually used to split two (sub-)projects, so that developers don't need to worry about taking each other's names.

Note: When I say "top-level namespace", I mean Razor.

Other Note: You're including some files several times; I'm assuming those are copy-paste mistakes.

Some ideas:

  • The namespaces should be defined inside each individual header, not in some global header. Including this header everywhere is going to cost you a lot of compile time. It'll also mean that an error in a single header file will not allow you to build any of your project, which can be inconvenient.
  • Do you really need a Framework namespace? It's just as big as your Razor namespace, so why bother with it? You could rename Razor to RazorFramework, and get the same effect. (If you decide to expand later, an Addons namespace may be more correct, anyway.)
  • Is File really that important a class to get its own namespace? Moreover, will you use the same File class for reading and writing all files, or is that possible to change? Again, I'd put it in the top-level namespace if it's so general, but I suspect there's more design decisions to be made about that file, anyway.
  • Graphics looks like a good choice for a namespace, but then you shouldn't prefix the files with Graphics. While not necessary, it's nice when your namespace structure and header structure are similar, if not identical.
  • Vertex looks like a common prefix: perhaps putting all vertex-related things in a namespace of their own would avoid that. The same may go for Buffer and Shader, depending on how likely those are to clash.
  • Functions and classes specific to OpenGL and DirectX are likely to be very similar, so having an OpenGL namespace and a DirectX namespace somewhere will let you use the same names for the same functionality in each.

Also, not related to namespaces, but if you want to have uppercase file names in the includes, make sure your actual file names are uppercase, too -- things will compile fine on Windows, but mysteriously break on other platforms (if you ever port there).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.