Um pouco mais sobre namespace

10 02 2008

namespaces em C++ são muito poderosos não servem apenas para proteger nomes em conflitos com outras bibliotecas, nos ajudam a implementar patterns como a bridge de uma forma mais clara, alem de deixar o código mais profissional.

namespace Engine
{
  namespace Video
  {
     namespace Gui
     {
         class Window
         {
             public:
               virtual ~Window() { }
         };
     }
  }
}

Você tambem poderia escrever dessa forma

using namespace Engine;
using namespace Video;
using namespace Gui;

shared_ptr<Window> window(new Window);

ou então

using Engine::Video::Gui::Window;

shared_ptr<Window> window(new Window);

Nesse exemplo usamos muitos namespaces, é raro encontrar casos como esse, apenas encontrei na engine Irrlicht (até 3 sub namespaces) e na boost (até 5 sub namespaces), o interessante é criar um aliases para o namespace da seguinte forma

// evg é um aliases para Engine::Video::Gui
namespace evg = Engine::Video::Gui;

shared_ptr<evg::Window> window(new evg::Window);

namespace “escopado”

{
  // EVG é um aliases para Engine::Video::Gui
  namespace EVG = Engine::Video::Gui;
  shared_ptr<EVG::Window> window(new EVG::Window);
}

{
  // Graphics é um aliases para Engine::Video
  namespace Graphics = Engine::Video;
  shared_ptr<Graphics::Gui::Window> window(new Graphics::Gui::Window);
}

{
  using namespace Engine;
  using namespace Video;
  using namespace Gui;

  shared_ptr<graphics::Gui::Window> window(new graphics::Gui::Window);
}

Veja que cada namespace tem seu próprio escopo.

Como boa pratica de programação prefira declarar apenas as classes que for usar de um namespace, ao invés de declará-lo todo.

Prefira usar

using std::string;
using std::vector;
using std::map;

Ao invés de

using namespace std;

Ou melhor ainda, se você tiver um projeto que use algum namespace, no seu header principal (global.h, internal.h), assim todos as classes declaradas podem ser usadas dentro do seu namespace, sem ter que ficar usando o using

namespace Wintermoon
{
  class Root;
  class Image;
  class ImageCache;
  class EventReceiver;
  class InputManager;
  ...

  using std::string;
  using std::vector;
  using std::map;
  using std::set;
  using std::multset;

  using std::for_each;
  using std::find;

  using boost::shared_ptr;
  using boost::scoped_ptr;
}