Namespaces are a feature of C++ which address the problem of name conflicts. There is a “global” namespace, where everything lives which was declared without namespace. Especially the Arduino environment declares a huge amount of variables and constants there, so it is a good practice to put everything you write in a own namespace. Namespaces are only used at compile time, and they do not use any memory at runtime or make your program slower.
In my case I choose the namespace lr
which stands for Lucky Resistor. Everything I declare in this namespace is accessible trough the ::
operator which you probably already know from function definitions.
namespace myone { class MyClass { }; } // end namespace myone::MyClass myClass;
As long you are inside of a namespace declaration, you do not have to add the given prefix:
namespace myone { class MyClass { public: MyClass(); // ctor }; MyClass::MyClass() { // ... } } // end namespace
How to use Classes and Types from a Namespace
If I like to use a class which is defined in its own namespace, I can choose to always prefix the types with the namespace or just import all names into the global namespace. Usually it is a good idea to prefix everything, to make clear from where you use a type. But sometimes importing the objects in the global namespace make things more readable. You can also import just a few types into the global namespace. You see there are endless possibilities.
As an example I will use the following class which is defined in the header file “MyClass.h”. Below I show you how to access the classes in different ways.
#pragma once namespace myns { class MyClass { public: enum State { On, Off }; public: MyClass(); void doWork(); void setState(State state); }; extern MyClass gMyClass; // global instance. } // end namespace
The header declares the class MyClass
in the namespace myns
and also a global instance of this class called gMyClass
, which is often used in Arduino libraries.
One way to access everything is just be prefixing all types with the namespace:
#include "MyClass.h" setup() { // Create a own instance of the class myns::MyClass myClass; myClass.doWork(); myClass.setState(myns::MyClass::On); // Use the global instance. myns::gMyClass.doWork(); myns::gMyClass.setState(myns::MyClass::Off); }
To simplify things, you can import single types or names into the global namespace. After the using myns::MyClass
you can use the class MyClass
without the need to prefix it with the namespace name. But the variable gMyClass
was not imported, therefore you have to add the prefix for this variable.
#include "MyClass.h" using myns::MyClass; setup() { // Create a own instance of the class MyClass myClass; myClass.doWork(); myClass.setState(MyClass::On); // Use the global instance. myns::gMyClass.doWork(); myns::gMyClass.setState(MyClass::Off); }
Now you could just add every name like this:
using myns::MyClass; using myns::gMyClass;
Or simple import the whole namespace:
#include "MyClass.h" using namespace myns; setup() { // Create a own instance of the class MyClass myClass; myClass.doWork(); myClass.setState(MyClass::On); // Use the global instance. gMyClass.doWork(); gMyClass.setState(MyClass::Off); } [/code]
Why this Prevents Naming Conflicts
For example you wrote a Stream
which controls the flow of water in the stream of your model railway project. You write a header as shown the the example below.
#pragma once class Stream { // ... };
If you try to compile this code, you will get an error message.
Stream.h:4:7: error: redefinition of 'class Stream'
One solution would be to rename you class, but you really like the name, or renaming would lead to even more conflicts. If you are using namespaces you will never run into these problems.
#pragma once namespace myns { class Stream { // ... }; }
Using your Class
If you use your library, you can choose to import your whole namespace into the global namespace. The conflicts are not gone of course, but you can selectively add prefixes where required.
#include "myns/Stream.h" #include "myns/Train.h" #include "myns/Signal.h" using namespace myns; setup() { Train train; train.start(); myns::Stream stream; // conflict, use prefix. stream.maximumFlow(); }
See also: How and Why to Avoid Preprocessor Macros
Learn More

Real Time Counter and Integer Overflow

Bit Manipulation using Templates

Event-Based Firmware (Part 2/2)

It’s Time to Use #pragma once

Guide to Modular Firmware

Awesome Article. I am so happy that I came across this.
Your article answered many of my questions.
I was looking for a good Arduino programming book and cannot find a single one on Amazon (using the ‘Look Inside’ feature) which lists the word ‘Namespace’ in the index!
You’ve managed to put the whys and hows of namespace clearly. I wish I found this earlier. I’ve had a vague understanding of namespace but not the details. Great piece!!