【问题标题】:Using Base pointers to call derived object function使用基指针调用派生对象函数
【发布时间】:2016-12-05 03:00:12
【问题描述】:

我需要能够使用基指针来保存 矩形或圆形。哪一个将在运行时确定。然后我想 根据类型使用指针调用不同的虚函数 他们是。如果函数只使用一个形状,我可以让这个概念发挥作用 指针。然而,我的许多功能需要两个对象才能工作。

如果我使用纯虚函数,则 Rectangle 和 Circle 类都变为 抽象,我不能使用对象(错误 C2259)。如果我声明函数 正如我在下面所做的那样,所有调用都转到基类 Shape。任何帮助都是 非常感谢。

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。 我想要 areaFF = 1.1 , areaFC = 1.2 , areaCC = 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 << "\n\n\tff : " << ff
        << "\n\tfc : " << fc
        << "\n\tcf : " << cf
        << "\n\tcc : " << cc;

    int pb; cin >> pb;
    return 0;
}

【问题讨论】:

  • 首先删除类中的类名限定符(例如 Circle::),如果您使用的是 C++11,请查找关键字“覆盖”。
  • 对 Rectangle:: 感到抱歉。我从一个程序中复制了一些代码,其中每个类都有一个单独的 .h 和 .cpp 文件
  • 啊,臭名昭著的double dispacth问题

标签: c++ inheritance signature overriding virtual-functions


【解决方案1】:

在基类中,除了现有的虚方法外,再定义两个纯虚方法,可以是纯虚方法。你需要做一些简单的前向声明:

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 &amp;参数调用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 参数,视情况而定。

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

【讨论】:

  • 为了记录,这是 Visitor 模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
相关资源
最近更新 更多