使用基本指针调用派生对象函数

Using Base pointers to call derived object function

本文关键字:派生 对象 函数 调用 指针      更新时间:2023-10-16

我需要能够使用基本指针来保存任何一个的地址矩形或圆圈。哪一个将在运行时间确定。然后我想 使用指针根据哪种类型调用不同的虚拟功能他们是。如果功能只使用一种形状,我可以使这个概念可以工作指针。但是,我的许多功能都需要两个对象才能起作用。

如果我使用纯虚拟函数,矩形和圆形类都变为摘要和我无法使用对象(错误C2259)。如果我声明功能正如我在下面所做的那样,所有呼叫都转到基类形状。任何帮助是非常感谢。

class Shape {
public:
    virtual double overlappingArea(const Shape&)const {return 0;};
    //replacing with a pure virtual function causes the other classes to become abstract
    //virtual double overlappingArea(const Shape&)const = 0;
    //This returns error C2259 (or pure virtual function has no overload)
    //I know this is because the program has no overloads with identical parameters
};
class Rectangle : virtual public Shape {
public:
    Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {}
    double overlappingArea(const Rectangle& R)const {
        double area = 1.1;
        //code that finds the overlapping area
        return area;
    }
    double overlappingArea(const Circle& C)const {
        double area = 1.2;
        //code that finds the overlapping area
        return area;
    }
private:
    int x, y, l, w;
};
class Circle: virtual public Shape {
public:
    Circle(int X, int Y, int R) : x(X), y(Y), r(R) {}
    double overlappingArea(const Rectangle& R)const {
        double area = 2.1;
        //code that finds the overlapping area
        return area;
    }
    double overlappingArea(const Circle& C)const {
        double area = 2.2;
        //code that finds the overlapping area
        return area;
    }
private:
    int x, y, r;
};
int main() {
    Shape* F1 = new Rectangle(0,0,1,1);
    Shape* F2 = new Rectangle(1,1,2,2);
    Shape* C1 = new Circle(0,0,1);
    Shape* C2 = new Circle(1,1,2);
    double areaFF, areaFC, areaCC;
    areaFF = F1->overlappingArea(*F2);
    areaFC = F1->overlappingArea(*C1);
    areaCC = C1->overlappingArea(*C2);    
    return 0;
}

所有区域最终都等于0。我想要abreatff = 1.1,aketfc = 1.2,aketcc = 2.2

感谢您的帮助
工作代码,如果您有兴趣

#include <iostream>
using namespace std;
class Rectangle;
class Circle;
class Shape {
public:
    virtual double overlapwith(const Shape&)const = 0;
    virtual double overlap(const Rectangle&)const = 0;
    virtual double overlap(const Circle&)const = 0;
};

class Circle : public Shape {
public:
    Circle() : x(0), y(0), r(0) {
    }
    Circle(int X, int Y, int R) : x(X), y(Y), r(R) {
    }
    double overlapwith(const Shape &with)const {
        cout << "nCirc::overlapwith(const Shap&)const";
        return with.overlap(*this);
    }
    double overlap(const Rectangle &w)const {
        cout << "nCirc::overlap(const Rect&)const";
        return 12;
    }
    double overlap(const Circle &w)const {
        cout << "nCirc::overlap(const Circ&)const";
        return 11;
    }
private:
    int x, y, r;
};
class Rectangle : public Shape {
public:
    Rectangle() : x(0), y(0), l(0), w(0) {
    }
    Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {
    }
    double overlapwith(const Shape &with)const {
        cout << "nRect::overlapwith(const Shap&)const";
        return with.overlap(*this);
    }
    double overlap(const Rectangle &w)const {
        cout << "nRect::overlap(const Rect&)const";
        return 22;
    }
    double overlap(const Circle &w)const {
        cout << "nRect::overlap(const Circ&)const";
        return 21;
    }
private:
    int x, y, l, w;
};


int main() {
    Shape* F1 = new Rectangle(0,0,1,1);
    Shape* F2 = new Rectangle(1,1,2,2);
    Shape* C1 = new Circle(0,0,1);
    Shape* C2 = new Circle(1,1,2);

    double ff, fc, cf, cc;
    ff = F1->overlapwith(*F2);
    fc = F1->overlapwith(*C2);
    cf = C1->overlapwith(*F2);
    cc = C1->overlapwith(*C2);
    cout << "nntff : " << ff
        << "ntfc : " << fc
        << "ntcf : " << cf
        << "ntcc : " << cc;
    int pb; cin >> pb;
    return 0;
}

除了现有的虚拟方法外,可以在基类中定义另外两个纯虚拟方法,这可以是纯粹的。您将需要做一些简单的远期声明:

class Rectangle;
class Circle;
class Shape {
public:
    virtual double overlappingArea(const Shape&) const=0;
    virtual double overlappingAreaWith(const Rectangle&) const=0;
    virtual double overlappingAreaWith(const Circle&) const=0;
};

在每个子类中,通过调用传递的Shape &参数的overlappingAreaWith()来实现第一个虚拟方法(现有方法),将*this作为参数传递:

class Rectangle {
    // ...
    double overlappingArea(const Shape &with) const override
    {
        return with.overlappingAreaWith(*this);
    }
};
class Circle {
    // ...
    double overlappingArea(const Shape &with) const override
    {
        return with.overlappingAreaWith(*this);
    }
};

现在,在CircleRectangle子类中实现其他两个overlappingAreaWith()方法。他们现在将接收另一个对象,例如CircleRectangle参数。

每个子类都正确地实现了所有三种纯虚拟方法。