有没有办法解决这个问题?我在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
答案 0 :(得分:3)
拥有IPrintable
界面,就像这样
struct IPrintable
{
virtual ~IPrintable() {}
virtual void Print() = 0;
};
然后,从Quad
派生您的类型Rectangle
,IPrintable
等,即实现该界面。然后您的代码如下所示:
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.
这个解决方案并不是特别漂亮,主要是因为它直接使用原始指针new
和delete
。更精美的版本将使用Factory
模式,返回智能指针。