C++;如何替换此if…else语句? 我有以下C++代码(简化版): 类形状 { bool isCircle=false; bool-isSquare=false; } 班级圈子:公共形态 { //一些特别成员/方法 } 阶级广场:公共形态 { //一些特别成员/方法 } 类CAD { 虚拟绘制圆(圆*圆)=0; } SWX类:公共CAD { 虚拟画圈(Circle*Circle){//在SWX系统上做一些画圈的事情} } class PRO:公共CAD { 虚拟画圈(Circle*Circle){//在PRO系统上做一些画圈的事情} } int main() { 圆圈*圆圈=新圆圈(); 圆->isCircle=true; Square*sq=新广场; sq->isSquare=true; 矢量形状; 形状。推回(圆形); 形状。推回(sq); SWX*SWX=新的SWX(); 对于(int i=0;iisCircle) { SWX->DrawCircle((圆*)(形状[i]); } else if(形状[i]->isSquare) { SWX->DrawSquare((正方形*)(形状[i]); } }
我希望不再需要if…else(如果在下文所述的限制范围内可能的话) 我现在的限制是:C++;如何替换此if…else语句? 我有以下C++代码(简化版): 类形状 { bool isCircle=false; bool-isSquare=false; } 班级圈子:公共形态 { //一些特别成员/方法 } 阶级广场:公共形态 { //一些特别成员/方法 } 类CAD { 虚拟绘制圆(圆*圆)=0; } SWX类:公共CAD { 虚拟画圈(Circle*Circle){//在SWX系统上做一些画圈的事情} } class PRO:公共CAD { 虚拟画圈(Circle*Circle){//在PRO系统上做一些画圈的事情} } int main() { 圆圈*圆圈=新圆圈(); 圆->isCircle=true; Square*sq=新广场; sq->isSquare=true; 矢量形状; 形状。推回(圆形); 形状。推回(sq); SWX*SWX=新的SWX(); 对于(int i=0;iisCircle) { SWX->DrawCircle((圆*)(形状[i]); } else if(形状[i]->isSquare) { SWX->DrawSquare((正方形*)(形状[i]); } },c++,polymorphism,C++,Polymorphism,我希望不再需要if…else(如果在下文所述的限制范围内可能的话) 我现在的限制是: CAD和派生类是具有各种外部依赖关系的大型类 CAD类不能与形状类和派生类合并(这很理想,因为我可以使用多态性来解决我的问题),因为其他项目/类依赖于形状类,而不能依赖于CAD类 有十几个形状派生类和六个CAD派生类,如果……其他派生类在许多地方发生,那么这将有助于任何简单易懂的解决方案(更容易说服我的队友更改遗留代码) 欢迎您提供任何建议/意见/解决方案。此问题的标准解决方案,特别是考虑到您对依赖关系的限
- CAD和派生类是具有各种外部依赖关系的大型类
- CAD类不能与形状类和派生类合并(这很理想,因为我可以使用多态性来解决我的问题),因为其他项目/类依赖于形状类,而不能依赖于CAD类
- 有十几个形状派生类和六个CAD派生类,如果……其他派生类在许多地方发生,那么这将有助于任何简单易懂的解决方案(更容易说服我的队友更改遗留代码)
欢迎您提供任何建议/意见/解决方案。此问题的标准解决方案,特别是考虑到您对依赖关系的限制,是使用 以下是访客模式在您的案例中的工作方式:
- 您需要一个抽象的
类。它对每个具体的Shape子类都有一个抽象的ShapeVisitor
方法。例如:Visit
,Visit(圆圈*)
,等等Visit(正方形*)
- Shape有一个抽象的
方法AcceptVisitor(ShapeVisitor*)
- 每个形状子类实现的
就像调用AcceptVisitor
visitor->Visit(this)
- 每个
类都是一个CAD
。ShapeVisitor
方法为特定类型的Visit
绘制适当的图形。无需条件或铸造Shape
class Circle;
class Square;
class ShapeVisitor
{
virtual void Visit(Circle *circle) = 0;
virtual void Visit(Square *square) = 0;
}
class Shape
{
virtual void AcceptVisitor(ShapeVisitor *visitor) = 0;
}
class Circle : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class Square : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class CAD : public ShapeVisitor
{
virtual DrawCircle(Circle *circle) = 0;
virtual DrawSquare(Square *square) = 0;
virtual void Visit(Circle *circle) {
DrawCircle(circle);
}
virtual void Visit(Square *square) {
DrawSquare(square);
}
}
class SWX : public CAD
{
virtual DrawCircle(Circle *circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
Square * sq = new Square;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->AcceptVisitor(SWX);
}
}
类圈;
班级广场;
类形位器
{
虚拟无效访问(圆圈*圆圈)=0;
虚拟无效访问(平方*平方)=0;
}
阶级形态
{
虚空接受访问者(ShapeVisitor*visitor)=0;
}
班级圈子:公共形态
{
//一些特别成员/方法
虚拟空接受访问者(ShapeVisitor*访问者)
{
访客->访问(本);
}
}
阶级广场:公共形态
{
//一些特别成员/方法
虚拟空接受访问者(ShapeVisitor*访问者)
{
访客->访问(本);
}
}
CAD类:公共形状显示器
{
虚拟绘制圆(圆*圆)=0;
虚拟DrawSquare(Square*Square)=0;
虚拟无效访问(圆圈*圆圈){
画圈(圈);
}
虚拟虚空访问(Square*Square){
广场(广场);
}
}
SWX类:公共CAD
{
虚拟画圈(Circle*Circle){//在SWX系统上做一些画圈的事情}
}
class PRO:公共CAD
{
虚拟画圈(Circle*Circle){//在PRO系统上做一些画圈的事情}
}
int main()
{
圆圈*圆圈=新圆圈();
Square*sq=新广场;
矢量形状;
形状。推回(圆形);
形状。推回(sq);
SWX*SWX=新的SWX();
对于(int i=0;iAcceptVisitor(SWX);
}
}
在这段代码中,我选择了使
CAD
实际上成为ShapeVisitor
的一个子类。此外,由于在CAD
中已经有了绘制图形的虚拟方法,我在那里实现了Visit
方法(一次),而不是在每个子类中一次。一旦您将客户端切换到使用AcceptVisitor
而不是直接调用Draw*方法,您就可以保护这些方法,然后最终将Visit
方法的实现移到子类中(也就是说:重构以消除由于调用Visit(Foo*)
callDrawFoo(Foo*)
)而导致的额外间接级别。这里有一些相当不可靠的OO,但至少DrawXxxx应该变成Draw()。圆形、方形和其他形状将定义Draw())方法,该方法为形状上的虚拟绘制方法提供实现。然后,您可以在任何形状上调用Draw,它将做正确的事情
isXxxx布尔值也应该去。类知道它们是什么,instanceof可以告诉你(尽管不需要检查何时绘制,因为这将是一个虚拟方法调用)。这是一个典型的例子,在这种情况下,你需要为每个可能的(形状、CAD)对使用一个单独的方法:
- 核化
/isSquare
字段isCircle
- 向
界面添加形状
虚拟空心绘图(CAD*)
- 实现
(例如): 这是一个“技巧”,它允许像Circle::drawin(CAD*)
这样的调用调用正确的方法,无论形状类型或CAD如何myCircle->drawin(mySWX)
- 这可能不是理想的解决方案,但是
class Circle;
class Square;
class ShapeVisitor
{
virtual void Visit(Circle *circle) = 0;
virtual void Visit(Square *square) = 0;
}
class Shape
{
virtual void AcceptVisitor(ShapeVisitor *visitor) = 0;
}
class Circle : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class Square : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class CAD : public ShapeVisitor
{
virtual DrawCircle(Circle *circle) = 0;
virtual DrawSquare(Square *square) = 0;
virtual void Visit(Circle *circle) {
DrawCircle(circle);
}
virtual void Visit(Square *square) {
DrawSquare(square);
}
}
class SWX : public CAD
{
virtual DrawCircle(Circle *circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
Square * sq = new Square;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->AcceptVisitor(SWX);
}
}
void Circle::DrawOn(CAD *c) {
c->DrawCircle(this);
}
class CAD {
public:
virtual void Draw(const Circle& circle) = 0;
virtual void Draw(const Square& square) = 0;
};
class Shape
{
virtual void DrawWithCAD(CAD * cad) = 0;
}
class Circle : public Shape
{
virtual void DrawWithCAD(CAD * cad)
{
cad->DrawCircle(this);
}
}
class Square : public Shape
{
virtual void DrawWithCAD(CAD * cad)
{
cad->DrawSquare(this);
}
}
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->DrawWithCAD(swx);
}
void Draw(CAD *cad, Circle *circle){
cad->DrawCircle(circle);
}
void Draw(CAD *cad, Square *square){
cad->DrawSquare(square);
}
class Shape
{
Draw(ICAD* cad) = 0;
}
class Circle : public Shape
{
Draw(ICAD* cad)
{
ICAD->DrawCircle(self)
}
}
class Square : public Shape
{
Draw(ICAD* cad)
{
ICAD->DrawSquare(self)
}
}
class ICAD
{
virtual DrawSquare(Square* square) = 0;
virtual DrawCircle(Circle * circle) = 0;
}
class CAD : public ICAD
{
// big CAD class...
}
class SWX : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
Square * sq = new Square;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->Draw(swx);
}
}