1. Consider the following scenario: Design a container that contains a set of different but interrelated objects (for example: Animal,dog,cat) with polymorphic behavior of the object.
2, the container can only contain one type of object, the use of vector<animal> will cause the object cutting, do not have polymorphic behavior.
3, the classic solution is: Vector<animal*>, but this will increase the burden of memory management. Consider the following scenario:
Dog D;
Vec[i] = &d; Local Object D destroy, Vec[i] point to garbage
Vec[i] = Vec[j]; Point to the same object, before the Vec destructor, you need to traverse the VEC manually, delete, two delete the same object, the behavior is undefined.
4, how to solve the above problem, each time create a new object. As follows:
Dog D;
Vec[i] = new Dog (d);
Vec[i] = new Animal (Vec[j]); There is a problem here, because the vec[j] type is unknown, only the animal is used, but this causes the object to be cut.
5. Handle objects of unknown type at compile time, using virtual method. Animal adds a pure virtual method clone, pure virtual method causes Animal to become an abstract class,
Cannot be instantiated and requires subclasses to override the Clone method. Note: Animal can provide a pure virtual method of clone implementation.
6, animal* pa = new Dog; Delete PA; To be able to invoke the destructor of the dog, it is a virtual method to define the animal of the method. Note: polymorphic behavior to meet two conditions:
The method is a virtual method, and the surface type is inconsistent with the true type.
7. Is there a better way?
Use the proxy class to manage animal*. That is, on the stack object management dynamic resources, using a C + + feature, the stack on the object out of scope, must call the Destructor method,
Frees the resource in the destructor method.
8, the code is as follows:
Animalproxy::animalproxy (): _pa (NULL)
{
}
Animalproxy::~animalproxy ()
{
Delete _pa;
}
Note: You can access your private members in the class, or you can access the private members of RHS
Animalproxy::animalproxy (const animalproxy& RHS)
{
_PA = (Rhs._pa! = null? Rhs._pa->clone (): null);
}
animalproxy& animalproxy::operator= (const animalproxy& RHS)
{
if (this = &RHS)//equivalent test
{
Delete _pa; Delete NULL also no problem
_PA = (Rhs._pa! = null? Rhs._pa->clone (): null); Null-judged pointer
}
return *this; return reference
}
Animalproxy::animalproxy (const animal& Animal): _pa (Animal. Clone ())
{
}
"Meditations on C + +" proxy class