将子对象复制到父对象

时间:2018-12-26 16:06:29

标签: c++ oop

我有3个班级:ShapeRectangleCircleShape是另外两个类的父级。此类的定义在以下代码中:

#include <iostream>

using namespace std;

class Shape {
public:
    Shape() {

    }

    ~Shape() {

    }

    void set(float BORDER, string COLOR) {
        border = BORDER;
        color = COLOR;
    }

    double computeArea() {
        return 0;
    }

private:
    float border;
    string color;
};

class Circle : public Shape {
public:
    Circle() {

    }

    ~Circle() {

    }

    void setRadius(float RADIUS) {
        radius = RADIUS;
    }

    double computeArea() {
        return 3.14 * radius * radius;
    }

private:
    float radius;
};


class Rectangle : public Shape {
public:
    Rectangle() {

    }

    ~Rectangle() {

    }

    void setWidth(float w) {
        width = w;
    }

    void setLength(float l) {
        length = l;
    }

    double computeArea() {
        return width * length;
    }

private:
    float width;
    float length;
};

我从CircleRectangle类构建了两个对象。然后,我将这两个对象复制到Shape类中。按以下顺序运行computeArea()函数时,我得到0的结果。

int main() {
    Circle c;
    c.setRadius(3);
    Rectangle r;
    r.setWidth(4);
    r.setLength(5);

    Shape sh[2];

    sh[0] = c;
    sh[1] = r;

    cout << sh[0].computeArea() << endl;
    cout << sh[1].computeArea();

    return 0;
}

我想用正确的功能计算所有形状的面积。我该怎么办?

预先感谢

3 个答案:

答案 0 :(得分:3)

要扩展Fureeish所说的内容,请将代码更改为此:

int main() {
    Circle c;
    c.setRadius(3);
    Rectangle r;
    r.setWidth(4);
    r.setLength(5);

    Shape *sh[2];

    sh[0] = &c;
    sh[1] = &r;

    cout << sh[0]->computeArea() << endl;
    cout << sh[1]->computeArea();

    return 0;
}

并将computeArea(以及Shape的析构函数声明为virtual)声明为base R的析构函数。

将派生类分配给基类的对象称为“对象切片”,通常会导致不良结果。使用指针(或引用)可以避免这种情况。

答案 1 :(得分:0)

您似乎缺少了virtual关键字。

Shape 基类的析构函数也必须是虚拟的(以防万一您决定通过指向基类的指针来操纵任何派生对象)。

必须将函数computeArea()声明为虚拟的,例如virtual double computeArea() { ... }

#include <iostream>

using namespace std;

class Shape {
public:
    Shape() {

    }

    virtual ~Shape() {

    }

    void set(float BORDER, string COLOR) {
        border = BORDER;
        color = COLOR;
    }

    virtual double computeArea() {
        return 0;
    }

private:
    float border;
    string color;
};

class Circle : public Shape {
public:
    Circle() {

    }

    virtual ~Circle() {

    }

    void setRadius(float RADIUS) {
        radius = RADIUS;
    }

    virtual double computeArea() {
        return 3.14 * radius * radius;
    }

private:
    float radius;
};


class Rectangle : public Shape {
public:
    Rectangle() {

    }

    virtual ~Rectangle() {

    }

    void setWidth(float w) {
        width = w;
    }

    void setLength(float l) {
        length = l;
    }

    virtual double computeArea() {
        return width * length;
    }

private:
    float width;
    float length;
};

如果您使用的是C ++ 11或更高版本,则可以在overrride函数定义的末尾添加computeArea关键字,例如

    virtual double computeArea() override {
        return width * length;
    }

还有这个

    virtual double computeArea() override {
        return 3.14 * radius * radius;
    }

在各个类别中。

然后修改主要功能。

    int main() {
    Circle c;
    c.setRadius(3);
    Rectangle r;
    r.setWidth(4);
    r.setLength(5);

    Shape *sh1, *sh2;

    sh1 = &c;
    sh2 = &r;

    cout << sh1->computeArea() << endl;
    cout << sh2->computeArea();

    return 0;
}

编辑:另外,正如其他人指出的那样,您需要指向基类的指针,而无需将派生类对象复制到基类对象。请参阅修改后的main()函数。

答案 2 :(得分:0)

在Shape类中,将computeArea()作为抽象(或纯虚拟)方法:

virtual double computeArea() =0;