Some one posted the questions about this pattern but not having the solution of the question raised in my mind so posting with the queries i have...
In above example if all the instance are initialized by s_prototypes variable, and next time if any object of that will be replaced by new object in clone method then what will happen to existing object?? will it create memory leaks??
As far as I understand from above example two statement are confusing me
class Stooge {
public:
virtual Stooge* clone() = 0;
virtual void slap_stick() = 0;
};
class Factory {
public:
static Stooge* make_stooge( int choice );
private:
static Stooge* s_prototypes[4];
};
int main() {
vector roles;
int choice;
while (true) {
cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
cin >> choice;
if (choice == 0)
break;
roles.push_back(
Factory::make_stooge( choice ) );
}
for (int i=0; i < roles.size(); ++i)
roles[i]->slap_stick();
for (int i=0; i < roles.size(); ++i)
delete roles[i];
}
class Larry : public Stooge {
public:
Stooge* clone() { return new Larry; }
void slap_stick() {
cout << "Larry: poke eyes\n"; }
};
class Moe : public Stooge {
public:
Stooge* clone() { return new Moe; }
void slap_stick() {
cout << "Moe: slap head\n"; }
};
class Curly : public Stooge {
public:
Stooge* clone() { return new Curly; }
void slap_stick() {
cout << "Curly: suffer abuse\n"; }
};
Stooge* Factory::s_prototypes[] = {
0, new Larry, new Moe, new Curly
};
Stooge* Factory::make_stooge( int choice ) {
return s_prototypes[choice]->clone();
}
Output
Larry(1) Moe(2) Curly(3) Go(0): 2
Larry(1) Moe(2) Curly(3) Go(0): 1
Larry(1) Moe(2) Curly(3) Go(0): 3
Larry(1) Moe(2) Curly(3) Go(0): 0
Moe: slap head
Larry: poke eyes
Curly: suffer abuse
But when we call clone method by make_stooge method it will return new object,If that returns new object and replaces it with existing one then the existing object will create memory leak here(because new operator completely creates seperate object and not return existing one here)....
so this thing is confusing me with this example....
There is no memory leak in your code, because the newly created objects are carefully stored in a
vector
(hereroles
).They are then used from that vector, and destroyed before the program ends:
But a
return 0;
before exiting main would be nicer...And it is good practice to create a virtual destructor for classes intended to be derived: if any of
Larry
, etc. had a non trivial destructor, it would not be used when you delete them through a base class pointer:For the 4 static objects of
s_prototypes
, they are statically initialized at program startup before main is called, and they are never modified. Theirclone
method is called to create new objects, buts_prototype
will still point to the old object - the reason why it is important that the newly created objects are stored and deleted.There is indeed a memory leak for those 4 objects because they will never be explicitely destroyed. It is often considered as acceptable to leak that way static objects because their life time extends up to the program end, were all the memory is released. If it was important for the destructor to be called, you should also create static instances for them:
If you make the destruction explicit with:
and slightly change the end of the program:
The output will be like:
clearly showing that the static objects are destroyed after the end of the program.