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 */