/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby,
C#, OCaml, VB, Perl, Swift, Prolog, Javascript, Pascal, COBOL, HTML, CSS, JS
Code, Compile, Run and Debug online from anywhere in world.
Here we introduce a factory method, which is not fairing well with classes having
a different number of constructor arguments
*******************************************************************************/
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Animal
{
public:
Animal () {}
Animal (string name):_name (name) {}
virtual ~ Animal () {}
virtual void action () = 0;
string name () { return _name; }
private:
string _name = {"anonymous"};
};
class Cat:public Animal
{
public:
//constructor with two arguments
Cat (const string & name, const string & color)
:Animal (name), _color (color) {}
void action ()
{
cout << "I am a cat, my name is " << name ()
<< " and my fur color is " << _color << endl;
}
private:
string _color = {"undefined"};
};
class Bug:public Animal
{
public:
//constructor with three arguments
Bug (const string & name, const string & color, int legs)
:Animal (name), _color (color), _legs (legs) {}
void action ()
{
cout << "I am a bug, my name is " << name ()
<< " and my skin color is " << _color
<< " and I jump on " << _legs << " legs"<<endl;
}
private:
string _color = {"undefined"};
int _legs = { 0 };
};
class UnknownFormOfLife:public Animal
{
public:
void action ()
{
cout << "I am an unknown form of life" << endl;
}
};
struct Factory
{
//a counter, mostly to illustrade some side effect of construction
static int num_constructed;
//factory method
static unique_ptr<Animal> makeAnimal(const string& animal_type,
const string& name,
const string& color,
int legs=0)
{
unique_ptr<Animal> temp(nullptr);
if (animal_type=="cat")
temp.reset(new Cat(name,color));
else if (animal_type=="bug")
temp.reset(new Bug(name,color,legs));
else
temp.reset(new UnknownFormOfLife());
num_constructed++;
return temp;
}
};
//initialise the static member variable
int Factory::num_constructed=0;
int main ()
{
vector < shared_ptr < Animal >> animals;
//here it relies on defaultable parameter legs, so can pass only three
animals.push_back(Factory::makeAnimal("cat","Charlie","black"));
//here it uses all four arguments and passes four params
animals.push_back(Factory::makeAnimal("bug","Tom","green",8));
//here it needs to pass some dummy parameters
animals.push_back(Factory::makeAnimal("alien","",""));
for (auto a : animals)
a->action();
cout<<"Number of animals produced is "<<Factory::num_constructed<<endl;
}