#include <iostream>
using namespace std;
struct AbstractResource {
int ref_count;
virtual void do_something() = 0;
AbstractResource() : ref_count(0) {}
virtual ~AbstractResource(){}
};
struct Resource0 : public AbstractResource {
void do_something(){
cout << "Do somthing with Resource0 at " << this << endl;
}
Resource0() : AbstractResource() {
cout << "Created : Resource0 at " << this << endl;
}
~Resource0(){
cout << "Clean-uped : Resource0 at " << this << endl;
}
};
struct Resource1 : public AbstractResource {
void do_something(){
cout << "Do somthing with Resource1 at " << this << endl;
}
Resource1() : AbstractResource() {
cout << "Created : Resource1 at " << this << endl;
}
~Resource1(){
cout << "Clean-uped : Resource1 at " << this << endl;
}
};
struct Resource {
AbstractResource *delegatee;
void do_something() {
delegatee->do_something();
}
Resource(AbstractResource *resource)
: delegatee(resource) {
(delegatee->ref_count)++;
}
Resource(const Resource &orig)
: delegatee(orig.delegatee) {
(delegatee->ref_count)++;
}
Resource &operator=(const Resource &rhs){
if(delegatee != rhs.delegatee){
if(--(delegatee->ref_count) <= 0){
delete delegatee;
}
delegatee = rhs.delegatee;
(delegatee->ref_count)++;
}
return *this;
}
~Resource() {
if(--(delegatee->ref_count) < 1){
delete delegatee;
}
}
};
struct ResourceManager {
static Resource get_resource(const int &type){
return Resource((type != 0)
? (AbstractResource *)new Resource1()
: (AbstractResource *)new Resource0());
}
};
int main() {
Resource r0(ResourceManager::get_resource(0));
r0.do_something();
Resource r1(ResourceManager::get_resource(1));
r1.do_something();
{
Resource r0_copy(r0);
r0_copy.do_something();
Resource r1_another(ResourceManager::get_resource(1));
r1_another.do_something();
}
return 0;
}