在交换机中声明类对象,然后在交换机外部使用该变量

时间:2011-11-22 13:23:15

标签: c++ oop switch-statement

有没有办法解决这个问题?我在switch语句中声明了类对象,后来在交换机外部使用了该变量,只有在我将其余代码放在每个非常高效的情况下才有效。这是我的代码

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

2 个答案:

答案 0 :(得分:3)

拥有IPrintable界面,就像这样

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

然后,从Quad派生您的类型RectangleIPrintable等,即实现该界面。然后您的代码如下所示:

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

当然,如果常用功能不仅仅是打印,您也可以将这些功能添加到界面中。另请查看访客模式。根据您问题的具体情况,它可能对您有所帮助,也可能没有帮助。

答案 1 :(得分:1)

不,这是不可能的。 geo在编译时只能有一种类型,并且在运行时不能更改。

您可以使用动态分配和多态来执行类似操作,但它可能不是解决您问题的最佳方法。

知道Quad是其他人的基类,以下可能是一个有用的解决方案:

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.

这个解决方案并不是特别漂亮,主要是因为它直接使用原始指针newdelete。更精美的版本将使用Factory模式,返回智能指针。