Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 除了这种情况,还有更好的选择吗_C++_Oop_Casting - Fatal编程技术网

C++ 除了这种情况,还有更好的选择吗

C++ 除了这种情况,还有更好的选择吗,c++,oop,casting,C++,Oop,Casting,我在这里遇到了这种棘手的情况,因此基本上我被要求编写一个函数,如果我单击的点位于图形中,则返回指向图形的指针,如果该点不位于任何图形中,则返回null CFigure *ApplicationManager::GetFigure(int x, int y) const { //If a figure is found return a pointer to it. //if this point (x,y) does not belong to any figure return

我在这里遇到了这种棘手的情况,因此基本上我被要求编写一个函数,如果我单击的点位于图形中,则返回指向图形的指针,如果该点不位于任何图形中,则返回null

CFigure *ApplicationManager::GetFigure(int x, int y) const
{
    //If a figure is found return a pointer to it.
    //if this point (x,y) does not belong to any figure return NULL
    int c = 0;
    for (size_t i = 0; i < FigCount; i++)
    {
        if (dynamic_cast<CRectangle*> (FigList[i]))
        {
            CFigure* basepointer = FigList[i];
            Point A = static_cast<CRectangle*>(basepointer)->GetCorner1();
            Point B = static_cast<CRectangle*>(basepointer)->GetCorner2();

            if ((x>=A.x && x<=B.x) || (x<=A.x && x>=B.x))
            {
                if ((y >= A.y && x <= B.y) || (y <= A.y && x >= B.y))
                {
                    c++;
                }
            }
        }
        else if (dynamic_cast<CCircle*> (FigList[i]))
        {
            CFigure* basepointer = FigList[i];
            Point A = static_cast<CCircle*>(basepointer)->getCntr();
            int B = static_cast<CCircle*>(basepointer)->GetRadius();

             double distance = sqrt(pow((x - A.x), 2) + pow((y - A.y), 2));
            if (distance<=(double)B)
            {
                c++;
            }
        }
        else if (dynamic_cast<CLine*> (FigList[i]))
        {
            CFigure* basepointer = FigList[i];
            Point A = static_cast<CLine*>(basepointer)->getPoint1();
            Point B = static_cast<CLine*>(basepointer)->getpoint2();
            double distance1 = sqrt(pow((x - A.x), 2) + pow((y - A.y), 2)); //Distance from point to P1
            double distance2 = sqrt(pow((x - B.x), 2) + pow((y - B.y), 2)); //Distance from Point to P2
            double distance3 = sqrt(pow((B.x - A.x), 2) + pow((B.y - A.y), 2)); //Distance from P1 to P2
            if (distance1+distance2==distance3)
            {
                c++;
            }
        }
        else
        {
            CFigure* basepointer = FigList[i];
            Point p1 = static_cast<CTriangle*>(basepointer)->getp1();
            Point p2 = static_cast<CTriangle*>(basepointer)->getp2();
            Point p3 = static_cast<CTriangle*>(basepointer)->getp3();
            float alpha = (((float)p2.y - (float)p3.y)*((float)x - (float)p3.x) + ((float)p3.x - (float)p2.x)*((float)y - (float)p3.y)) /
                (((float)p2.y - (float)p3.y)*((float)p1.x - (float)p3.x) + ((float)p3.x - (float)p2.x)*((float)p1.y - (float)p3.y));
            float beta = (((float)p3.y - (float)p1.y)*((float)x - (float)p3.x) + ((float)p1.x - (float)p3.x)*((float)y - (float)p3.y)) /
                (((float)p2.y - (float)p3.y)*((float)p1.x - (float)p3.x) + ((float)p3.x - (float)p2.x)*((float)p1.y - (float)p3.y));
            float gamma = 1.0f - alpha - beta;
            if (alpha>0 && beta>0 && gamma >0)
            {
                c++;
            }
        }
    }

    ///Add your code here to search for a figure given a point x,y  
    if (c==0)
    {
        return NULL;
    }

}
如您所见,我还没有决定返回什么,但我的问题是使用dynamic cast在这里找到最佳解决方案

-CLine、CTriangle、CRectangle和CCircle都是来自CFigure的派生类

您可以使用虚拟函数将处理移动到每个派生类型中,而不是测试类型以决定如何处理它们

而不是这样做:

struct B {};
struct D1: B {};
struct D2: B {};

// ...

void func(B* b)
{
    int c = 0;

    if(dynamic_cast<D1*>(b))
    {
        // do D1 stuff
        c = ...
    }
    else if(dynamic_cast<D2*>(b))
    {
        // do D2 stuff
        c = ...
    }
}
类中的CFigure add

这是一个纯虚拟函数。CFigure的所有子类都必须实现它。子类的实现检查单击是否在其边界内,并相应地返回true或false

将ApplicationManager::GetFigure简化为

CFigure *ApplicationManager::GetFigure(int x, int y) const
{
    for (size_t i = 0; i < FigCount; i++)
    {
        if (FigList[i]->isclicked(x,y))
        {
            return FigList[i];
        }
    }
    return nullptr;
}

通过虚拟函数和多态性的魔力,该程序将无需您的进一步努力就可以确定需要调用哪个子类的isclick函数。

您应该通过每个类实现的多态方法实现命中检测。@OliverCharlesworth很抱歉,我没有遵循,已经有一个功能可以检测用户的位置clicked@AhmedKh,Oliver说的是,你所做的不是正确的OOP技术。基本上,在图形类型上有一个大的switch语句。更好的方法是在CFigure类中有一个抽象虚拟方法,让我们调用它contains,它返回一个bool,告诉您点是否在图形中。然后只需通过FigList和call contains,不需要强制转换即可。@pcarter那么你是说我应该在Cfigure中添加4个函数来检查这到底是什么数字?如果是,我是否也应该使用动态/静态转换?编辑:我指的是一个抽象的虚拟函数。谢谢你的帮助
virtual bool isclicked(int x, int y) = 0;
CFigure *ApplicationManager::GetFigure(int x, int y) const
{
    for (size_t i = 0; i < FigCount; i++)
    {
        if (FigList[i]->isclicked(x,y))
        {
            return FigList[i];
        }
    }
    return nullptr;
}