Копировать дочерний объект в родительский объект - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть три класса: Shape, Rectangle и Circle.Shape является родителем двух других классов.определение этих классов в следующем коде:

#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;
};

Я строю два объекта из Circle и Rectangle классов.Затем я скопировал эти два объекта в класс 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 голосов
/ 26 декабря 2018

В классе Shape сделайте computeArea () абстрактным (или чисто виртуальным) методом:

virtual double computeArea() =0;
0 голосов
/ 26 декабря 2018

Чтобы расширить то, что сказал 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.

Присвоение производного класса объекту базового класса называется «разрезанием объекта» и обычно приводит к нежелательным результатам.Использование указателей (или ссылок) позволяет избежать этого.

0 голосов
/ 26 декабря 2018

Кажется, вам не хватает ключевого слова 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 (), пожалуйста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...