Allen napisal(a):
Quote:
Square *square = reinterpret_cast<Square*>(mcreator.Create(2));
It is VERY BAD, UNSAFE practice to use reinterpret_cast here! Proper
way is to use dynamic_cast.
My proposal is:
class Quad
{
public:
void Area(); // not needed, it should be dropped out
virtual void Desc() = 0; // every derived class will have to
// implement this function
};
/*-------- Square ----------*/
class Square : public Quad
{
public:
void Area(int x);
void Desc();
};
void Square::Area(int x)
{
cout << "Area of square is = " << x*x << endl;
}
void Square::Desc()
{
cout << "This Derived class Square from Base Class Quad" << endl;
}
/*------ Rectangle ---------*/
class Rectangle : public Quad
{
public:
void Area(int x, int y);
void Desc();
};
void Rectangle::Area(int x, int y)
{
cout << "Area of Rectangle is = " << x*y << endl;
}
void Desc()
{
cout << "This Derived class Rectangle from Base Class Quad" << endl;
}
/*-------- Creator -----------*/
class Creator
{
public:
Quad* Create(const int id);
};
Quad* Creator::Create(const int id)
{
if (id == 2)
return new Square();
else
return new Rectangle();
}
/*--------- Let's use this stuff -------*/
int main(int argc, char* argv[])
{
Creator mcreator;
if (argc <= 2) {
// below we use dynamic_cast. It checks if Square is really
// a subclass of this Quad object and then does casting
Square* square = dynamic_cast<Square*>(mcreator.Create(argc));
square->Area(3);
square->Desc();
// do not forget to do some cleanups, to avoid memory leaks
delete square;
} else {
Rectangle* rectangle =
dynamic_cast<Rectangle*>(mcreator.Create(argc));
rectangle->Area(3,4);
rectangle->Desc();
delete rectangle;
}
return 0;
}
/*----- Another, more compact and safe version --------*/
int main(int argc, char* argv[])
{
Creator mcreator;
Quad* quad = mcreator.Create(argc);
if (argc <= 2) {
dynamic_cast<Square*>(quad)->Area(3);
} else {
dynamic_cast<Rectangle*>(quad)->Area(3,4);
}
quad->Desc(); // it uses Desc() version of Square or Rectangle,
// according to type of created object,
// beacause Quad.Desc() is virtual
delete quad;
return 0;
}