Jea*_*ean 0 c++ polymorphism inheritance
我有一个基类Shape,派生类和Ellipse和Rectangle.
在一个函数中,我有一个变量:
Shape activeShape(black, black, {0,0}, {0,0}, false);
后来在那个函数中:
activeShape = updateShape(isButton, activeShape, true);
updateShape 看起来像这样:
Shape updateShape(int button, Shape active, bool leftClick)
{
switch(button)
{
case 1:
return active;
case 2:
return Line(active.getFillColor(), active.getBorderColor(), active.getP1(), active.getP2(),false);
break;
case 3:
return Rectangle(active.getFillColor(), active.getBorderColor(), active.getP1(), active.getP2(),false);
break;
case 4:
return FilledRectangle(active.getFillColor(), active.getBorderColor(), active.getP1(), active.getP2(),false);
break;
case 5:
return Ellipse(active.getFillColor(), active.getBorderColor(), active.getP1(), active.getP2(),false);
break;
case 6:
return FilledEllipse(active.getFillColor(), active.getBorderColor(), active.getP1(), active.getP2(),false);
break;
default:
if(leftClick)
{
active.setColor(getEnumColor(button), active.getBorderColor());
}
else
active.setColor(active.getFillColor(), getEnumColor(button));
break;
};
return active;
}
Run Code Online (Sandbox Code Playgroud)
因此,当我回归之类的时候Rectangle,它们就像是一样Shape.这不是我想要的.
我需要做什么activeShape才能成为Shape派生类之一?
一旦创建了对象,就不可能变形其类型(例如,基于在运行时获得的按钮的信息).返回a Rectangle作为Shape具有切片对象的效果,因此调用者只接收该Shape部分的副本Rectangle,而不是其余部分的副本.
假设Shape是一个多态基类(即它提供了可能由派生类专门化的虚函数),Shape *(指向形状的指针)可以指向a Rectangle.但是,必须正确管理对象的生命周期.
您可以使用智能指针处理所有这些,例如,在C++ 11及更高版本中std::unique_pointer<Shape>.
std::unique_pointer<Shape> updateShape(int button,
std::unique_pointer<Shape> active, bool leftClick)
{
switch(button)
{
case 1:
break; // don't change active
case 2:
active = new Line(active->getFillColor(), active->getBorderColor(), active->getP1(), active->getP2(),false);
break;
case 3:
active = new Rectangle(active->getFillColor(), active->getBorderColor(), active->getP1(), active->getP2(),false);
break;
case 4:
active = new FilledRectangle(active->getFillColor(), active->getBorderColor(), active->getP1(), active->getP2(),false);
break;
case 5:
active = new Ellipse(active->getFillColor(), active->getBorderColor(), active->getP1(), active->getP2(),false);
break;
case 6:
active = new FilledEllipse(active->getFillColor(), active->getBorderColor(), active->getP1(), active->getP2(),false);
break;
default:
if(leftClick)
{
active->setColor(getEnumColor(button), active->getBorderColor());
}
else
{
active->setColor(active->getFillColor(), getEnumColor(button));
}
break;
}
return active;
}
Run Code Online (Sandbox Code Playgroud)
这样做的原因是std::unique_pointer管理动态分配(使用运算符创建new)对象的生命周期.它通过存储指向对象的指针,并指定std::unique_pointer<Shape>更改指针(使其指向不同的对象)来完成此操作.重要的是,分配给智能指针也会释放它先前管理的对象.
请注意,因为在生命周期结束时std::unique_pointer将使用运算符delete来销毁包含的对象,所以Shape必须有一个虚拟析构函数.如果不这样做,将导致使用运算符时出现未定义的行为delete.
使用这个就像是
std::unique_pointer<Shape> activeShape(new Rectangle( whatever_parameters));
activeShape = updateShape(button, activeShape, leftClick);
Run Code Online (Sandbox Code Playgroud)
请记住,这activeShape是一个智能指针.因此,使用包含的Shape对象需要指针语法(activeShape->whatever)而不是成员语法(activeShape.whatever).
因为active参数(通过值)传递给函数并返回,所以指定返回值是必需的.如果,而不是
activeShape = updateShape(button, activeShape, leftClick);
Run Code Online (Sandbox Code Playgroud)
你干脆
updateShape(button, activeShape, leftClick); // returned object is discarded
Run Code Online (Sandbox Code Playgroud)
(即不将返回值赋值给任何东西),净效果是activeShape被销毁的对象将被销毁,任何使用它的尝试都会给出未定义的行为.