Basic C++ Circle Class I'm trying to improve on my basic C++ skills and create really nice, concise and clean code that is free from artifacts. 

The program can add and subtract radius values from each circle, assign one circle to another and furthermore give the area. 

Any tips on how this program can be improved, whether considering readability issue or anything else would be great. 

//  Basic circle exercise 23rd March

#include &lt;cstdio&gt;
#include &lt;math.h&gt;

using namespace std;

//==============================================================================
/*                               interface                                    */
//==============================================================================
namespace corey
{
    class Circle
    {
    public:
        Circle(const int &amp; r = 1.0);
        ~Circle();

        const double &amp; getRadius() const;
        const double getArea() const;

        Circle &amp; operator = (const Circle &amp;);
    private:
        double radius;
    };
};


//==============================================================================
/*                              implementation                                */
//==============================================================================
/*I'd probably included using namespace corey if
    i'd have bothered with seperate files*/

corey::Circle::Circle(const int &amp; r) : radius(r){}

corey::Circle::~Circle(){}

const double &amp; corey::Circle::getRadius() const
{
    return radius;
}

const double corey::Circle::getArea() const
{
    const double area = (M_PI * radius * radius);
    return area;
}

corey::Circle operator + ( const corey::Circle &amp; lhs, const corey::Circle &amp; rhs)
{
    return corey::Circle(lhs.getRadius() + rhs.getRadius());
}

corey::Circle operator - ( const corey::Circle &amp; lhs, const corey::Circle &amp; rhs)
{
    return corey::Circle(lhs.getRadius() - rhs.getRadius());
}

corey::Circle &amp; corey::Circle::operator = (const Circle &amp; lhs)
{
    if(&amp;lhs != this)
    {
        radius = lhs.radius;
    }
    return (*this);
}


//==============================================================================
/*                                   useage                                   */
//==============================================================================
int main( int argc, char ** argv )
{
    //this stuff is just some info printed out so not super important...
    corey::Circle c1(2);
    printf("Circle made with radius %lf &amp; area %lf\n", c1.getRadius(), c1.getArea());

    const corey::Circle c2(6);
    printf("Circle made with radius %lf &amp; area %lf\n", c2.getRadius(), c2.getArea());

    corey::Circle c3;
    c3 = c2 + c1;
    printf("Circle made with radius %lf &amp; area %lf\n", c3.getRadius(), c3.getArea());

    c1 = c3;
    printf("Circle made with radius %lf &amp; area %lf\n", c1.getRadius(), c1.getArea());

    return 0;
}
Be consistent with #include
We have C++ &lt;cstdio&gt; (which defines the C names in the std namespace), but the C-style &lt;math.h&gt; (which puts the identifiers in the global namespace).  For new C++ code, prefer &lt;cmath&gt;.  And don't use using namespace std; - that can be harmful.
Allow the compiler to define assignment
We don't need to do anything in operator=() that's different from the compiler-generated (member-by-member copy) assignment.  Declaring our own actually prevents some optimizations that can be done for so-called &quot;trivial&quot; types (without the operator, the compiler knows it can simply copy the object's memory, but with one, it must assume that copying is more involved than that; it also inhibits the generation of a move assignment operator).
Similarly, we don't need to define a destructor - let the compiler generate that, too.
Pass by value for primitive types
There's no benefit to passing a reference to const int in the constructor - just pass the int by value.  That's simpler and (before optimization) faster.
Actually, why is this an int, when we could accept any double value?  And why is the default 1.0?  I think that 0.0 (an empty circle) would be less surprising (it's then more like the numbers, where default initialization uses zero).  Consider also some validation - is a negative radius meaningful for your code?
It's better to return double by value from getRadius() for much the same reasons.
Mark the constructor explicit
Unless you like surprises, it's better if you don't allow numbers to convert automatically to circles.
Don't return 'const' values
The const double return type of getArea() is no different to plain double - the const will be ignored (and that's a good thing).  So it's useless clutter to write it (and GCC will warn you, assuming you turn on a reasonable set of warnings).
Operators
What does it mean to subtract one circle from another?  In a geometry library, I'd want to get an annulus back (i.e. a circle with a hole cut out) or not be allowed to subtract at all.  Similarly for addition.
If you do choose to provide operators, you'll want to declare them with your interface (so this could be moved to a header).  And you should consider whether to provide the corresponding assignment operators (+= and -=).
On the positive, you have the correct argument and return types here.
Portability
Your environment clearly provides you with M_PI for a value of π.  That's not a standard identifier, and although it's a common extension, it's more portable to define your own.  Popular expressions producing π include 4 * std::atan(1) and std::acos(-1)  These are both compile-time constants, so cost nothing to the program's users.
A thing I like in the getArea() is that you write radius * radius and didn't get seduced by std::pow(radius, 2) - which is generally slower and less accurate than multiplication (it's more versatile, because it supports fractional powers, but we don't need that here).
Prefer C++ formatted output
The &lt;iostream&gt; header provides I/O with better type-checking than the C-style &lt;cstdio&gt; functions.  Consider providing a &lt;&lt; operator to stream to a standard library stream.

Modified code

#include &lt;cmath&gt;
#include &lt;iosfwd&gt;

namespace corey
{
    class Circle
    {
        static constexpr double pi = 4 * std::atan(1);
        double radius;

    public:
        explicit Circle(double r = 0);

        double getRadius() const;
        double getArea() const;
    };

    Circle operator+(const Circle&amp;, const Circle&amp;);
    Circle operator-(const Circle&amp;, const Circle&amp;);

    std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Circle&amp;);
}


#include &lt;ostream&gt;

namespace corey {
    Circle::Circle(double r)
        : radius(r)
    {}

    double Circle::getRadius() const
    {
        return radius;
    }

    double Circle::getArea() const
    {
        return pi * radius * radius;
    }

    Circle operator+(const Circle&amp; lhs, const Circle&amp; rhs)
    {
        return Circle(lhs.getRadius() + rhs.getRadius());
    }

    Circle operator-(const Circle&amp; lhs, const Circle&amp; rhs)
    {
        return Circle(lhs.getRadius() - rhs.getRadius());
    }

    std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const Circle&amp; c)
    {
        return os &lt;&lt; &quot;Circle made with radius &quot; &lt;&lt; c.getRadius()
                  &lt;&lt; &quot; &amp; area &quot; &lt;&lt; c.getArea();
    }
}


#include &lt;iostream&gt;

int main()
{
    using corey::Circle;

    Circle c1(2);
    std::cout &lt;&lt; c1 &lt;&lt; '\n';

    const Circle c2(6);
    std::cout &lt;&lt; c2 &lt;&lt; '\n';

    Circle c3;
    c3 = c2 + c1;
    std::cout &lt;&lt; c3 &lt;&lt; '\n';

    c1 = c3;
    std::cout &lt;&lt; c1 &lt;&lt; '\n';
}