Listing 1: circle implemented with COM-like abstraction technique

#include <iostream>

class common_interface
    {
public:
    virtual void add_reference() = 0;
    virtual void release() = 0;
    virtual common_interface *query_interface(unsigned)
            = 0;
    };

class circle_interface : public common_interface
    {
public:
    virtual double get_area() const = 0;
    virtual void set_radius(double) = 0;
    //
    //  Derived from 'common_interface'.
    //
    virtual void add_reference() = 0;
    virtual void release() = 0;
    virtual common_interface *query_interface(unsigned)
            = 0;
    };

class circle_implementation : public circle_interface
    {
public:
    ~circle_implementation();
    circle_implementation();
    circle_implementation(circle_implementation const &);
    circle_implementation &operator=
            (circle_implementation const &);
    common_interface *create_interface(unsigned);
private:
    double radius_;
    unsigned reference_count_;
    //
    //  Derived from 'common_interface'.
    //
    virtual void add_reference();
    virtual void release();
    virtual common_interface *query_interface(unsigned);
    //
    //  Derived from 'circle_interface'.
    //
    virtual double get_area() const;
    virtual void set_radius(double);
    };

//
//  Magic unique identifiers for the two interface
//  classes we've defined.  Client code queries for
//  objects that implement these interfaces by keying on
//  these unique IDs.
//

unsigned const COMMON_ID = 0;
unsigned const CIRCLE_ID = 1;

circle_implementation::~circle_implementation()
    {
    }
circle_implementation::circle_implementation() :
        radius_(0), reference_count_(0)
    {
    }

circle_implementation::circle_implementation
        (circle_implementation const &that) :
        radius_(that.radius_), reference_count_(0)
    {
    }

circle_implementation &circle_implementation::operator=
        (circle_implementation const &that)
    {
    if (static_cast<void const *>(this) !=
            static_cast<void const *>(&that))
        {
        radius_ = that.radius_;
        reference_count_ = 0;
        }
    return *this;
    }

common_interface *circle_implementation::create_interface
        (unsigned id)
    {
    return query_interface(id);
    }

void
circle_implementation::add_reference()
    {
    ++reference_count_;
    }

void circle_implementation::release()
    {
    if (reference_count_ > 0)
        --reference_count_;
    }

common_interface *circle_implementation::query_interface
        (unsigned id)
    {
    common_interface *result = NULL;
    if (id == COMMON_ID)
        result = this;
    else if (id == CIRCLE_ID)
        result = dynamic_cast<circle_interface *>(this);
    if (result != NULL)
        add_reference();
    return result;
    }

double circle_implementation::get_area() const
    {
    return 3.14159265 * radius_ * radius_;
    }

void circle_implementation::set_radius(double radius)
    {
    radius_ = radius;
    }

void create_circle_implementation
        (circle_implementation **implementation)
    {
    *implementation = new circle_implementation;
    }

void destroy_circle_implementation
         (circle_implementation *implementation)
    {
    delete implementation;
    }
/* End of File */