Hello,
I am working on an event driven library and am having one minor problem. Basically I have two ways to get what I want done.
Method 1: Smart pointers and factory functions
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Object
{
public:
virtual int getInt(){return 0;}
static shared_ptr<Object> create()
{// of course this could be replaced with the templated version to make it work for any constructor
return shared_ptr<Object>(new Object());
}
};
class One:public Object
{
public:
virtual int getInt(){return 1;}
static shared_ptr<One> create()
{
return shared_ptr<One>(new One());
}
};
class Incrementer:public Object
{
int x;
public:
Incrementer():x(0){}
Incrementer(int i):x(i){}
virtual int getInt(){return x++;}
static shared_ptr<Incrementer> create()
{
return shared_ptr<Incrementer>(new Incrementer());
}
};
class Scene
{
vector<shared_ptr<Object> > os;
public:
Scene &add(shared_ptr<Object> o)
{
os.push_back(o);
return *this;
}
Scene &print(){
for (size_t i=0; i<os.size(); ++i)
cout<<os[i]->getInt()<<endl;
return *this;
}
};
int main() {
Scene s;
s.add(One::create());
s.add(Incrementer::create());
s.print().print().print();
return 0;
}
Method 2: Clone function
#include <iostream>
#include <vector>
using namespace std;
class Object
{
public:
virtual int getInt(){return 0;}
virtual Object* clone(){return new Object;}
};
class One:public Object
{
public:
virtual int getInt(){return 1;}
virtual One* clone(){return new One;}
};
class Incrementer:public Object
{
int x;
public:
Incrementer():x(0){}
Incrementer(int i):x(i){}
virtual int getInt(){return x++;}
virtual Incrementer* clone(){return new Incrementer(x);}
};
class Scene
{
vector<Object *> os;
public:
Scene &add(Object *o)
{
os.push_back(o->clone());
}
Scene &print(){
for (size_t i=0; i<os.size(); ++i)
cout<<os[i]->getInt()<<endl;
return *this;
}
~Scene()
{
for (size_t i=0; i<os.size(); ++i)
delete os[i];
}
};
int main() {
Scene s;
Incrementer i;
{
One *one=new One;
s.add(one);
delete one;
}
s.add(&i);
s.print().print().print();
return 0;
}
I tend to prefer method 1 (it looks cleaner, and is less prone to error) however both have a problem in that they both require that the user add a function to every class that they wish to use. If they forget to write a create() or clone() function then the library would fail. Is it possible to achieve this kind of functionality without forcing the user to add a specific function to each class?