Using namespaces to avoid naming conflicts

Tuesday, May 4, 2021
Design C++

In the last post, we saw how to encapsulate data and methods in C++ classes. Now the question is what if another class with the same name (Circle in our example) exists somewhere else in the codebase? How does the compiler know which Circle class to use? Well, we can wrap our class defnition inside a namespace block and then refer to it while creating an object. In fact, that is what std::cout is doing - we are telling the compiler to use the function cout from std namespace. Let's see how we can do this for our Circle class. In the example below, we wrap both class declaration and definitions inside a namespace called geom.

/*
/* header file for Circle class
/* Circle.h
*/

#pragma once

namespace geom {
    class Circle {
        public:
            void setRadius(double radius);
            double getPerimeter();
            double getArea();

        private:
            double radius_;

    };
}

/*
/* Source code (Circle.cpp) for Circle class
*/

#include "Circle.h"

namespace geom {
    void Circle::setRadius(double radius) {
        radius_ = radius;
    }

    double Circle::getPerimeter() {
        return 2 * 3.1415 * radius_;
    }

    double Circle::getArea() {
        return 3.1415 * radius_ * radius_;
    }
}

We create the object from our circle class by prepending the class name with geom:: like so:

#include <iostream>
#include "Circle.h"
using std::cout;
using std::endl;

int main() {
    geom::Circle c; // creating a Circle object from geom namespace
    c.setRadius(1);
    cout << "Perimeter: " << c.getPerimeter() << endl;
    cout << "Area: " << c.getArea() << endl;
    
    return 0;
}
~/lab/cpp/circle$ g++ -o main main.cpp Circle.cpp 
~/lab/cpp/circle$ ./main
Perimeter: 6.283
Area: 3.1415
~/lab/cpp/circle$