declaring class objects in a switch and later usin

2020-04-15 13:36发布

问题:

Is there a way to work around this?Im declaring class objects in a switch statement and later using that variable outside the switch, it only works if i put the rest of my code in each case which isnt very efficient.Heres my code

switch (shape)
{
case 'q':
{
    Quad geo(a,b,c,d);
}
break;
case 'r':
{
    Rectangle geo(a,b,c,d);
}
break;
case 't':
{
    Trapezoid geo(a,b,c,d);
}
break;
case 'p':
{
    Parrelogram geo(a,b,c,d);
}
break;
case 's':
{
    Square geo(a,b,c,d);

}
break;
default:
    break;
}

 geo.print();//obviously wont work

回答1:

Have an IPrintable interface, like this

struct IPrintable
{
    virtual ~IPrintable() {}
    virtual void Print() = 0;
};

Then, derive your types Quad, Rectangle, etc from IPrintable, i.e. implement that interface. Then your code looks like this:

std::unique_ptr<IPrintable> pShape;
switch(shape)
{
    case quad:
       pShape.reset(new Quad(...));
    case rect
       pShape.reset(new Rect(...));
}
if(pShape)
    pShape->Print();

Of course, if the common functionality is more than print, you can add those functions to the interface as well. Also take a look at the visitor pattern. It may or may not be of help to you depending on the specifics of your problem.



回答2:

No, it is not possible. geo can only have one type at compile time, and it cannot change at runtime.

You could do something similar with dynamic allocation and polymorphism, but it might not be the best solution to your problem.

With the knowledge that Quad is the base class of the others, the following might be a usable solution:

Quad* geo = 0;
switch (shape) {
case 'q':
    geo = new Quad(a,b,c,d);
    break;
case 'r':
    geo = new Rectangle(a,b,c,d);
...
default:
    break;
}
if (geo) geo->print();
delete geo; // Ok if geo is 0.

This solution is not particularly pretty, mainly because it uses raw pointers and new and delete directly. A more polished version would use the Factorypattern, returning a smart pointer.