Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Вызов дочернего метода через базовый класс

#cpp #ооп #виртуальная_функция


Есть базовый класс Shapes, в нем есть два абстрактных метода P (Периметр) и S (Площадь).
Также есть дочерний класс Circle, в котором реализованы методы P и S с помощью полиморфизма. 

Вопрос: как вызвать метод P и S из класса Circle через класс Shapes? 

Это же называется динамическое связывание?

Shapes.h

class Shpes
{
private:    
public:
    Shpes();
    virtual double P() = 0;
    virtual double S() = 0;
};

Shpes::Shpes()
{

}


Circle.h 

#include "Shpes.h"

class Circle :
    public Shpes
{
private: 
    double r;
    void SetCheck(double R);

public: 
    Circle(double R = 0);
    virtual double P();
    virtual double S();
    void Print();
};


Circle.cpp

#include "Circle.h"
#include 
#include 

using namespace std;

void Circle::SetCheck(double R)
{
    R < 0 ? r = abs(R) : r = R; 
}

Circle::Circle(double R)
{
    SetCheck(R);
}

double Circle::P()
{   
    return 2 * 3.12 * r;
}

double Circle::S()
{   
    return 3.14 * r * r;
}

void Circle::Print()
{
    cout << "При радиусе круга = " << r <

Ответ 1



Это можно сделать через указатель или ссылку на базовый класс, инициализированными объектом производного класса. Например, Circle c( 10 ); Shape *ps = &c; ps->R(); ps->S(); Shape &rs = c; rs.R(); rs.S(); Имейте в виду, что деструктор в базовом классе также следует объявить как виртуальный. Например, virtual ~Shape() = default; или virtual ~Shape(){} ОБратите внимание на расхождение double Circle::P() { return 2 * 3.12 * r; ^^^^^ } double Circle::S() { return 3.14 * r * r; ^^^^ } Чтобы не допускать такого вида ошибки, лучше используемым константам назначать имена. Вы могли бы определить соответствующий член в вашем классе (при условии, что компилятор поддерживает данную конструкцию), например, class Circle : public Shpes { private: double r; void SetCheck(double R); constexpr static double PI = 3.14; public: Circle(double R = 0); virtual double P(); virtual double S(); void Print(); }; И записать определения функций следующим образом double Circle::P() { return 2 * PI * r; ^^^^^ } double Circle::S() { return PI * r * r; ^^^^ } Если компилятор не поддерживает такое объявление члена класса, то можно просто написать class Circle : public Shpes { private: double r; void SetCheck(double R); const static double PI; public: Circle(double R = 0); virtual double P(); virtual double S(); void Print(); }; И затем определить эту статическую переменную double Circle::PI = 3.14;

Ответ 2



Очень просто: Shpes *figure = new Circle( 1 ); cout << figure->P() << endl;

Комментариев нет:

Отправить комментарий