Доступ к внучатому классу с помощью полиморфизма в переполнении стека

Меня попросили реализовать эту диаграмму в полиморфизме, который выводится для расчета геометрии:

Критерии следующие:

  • Функции print () и getArea () помещаются в базовый класс Shape. Также спрашивают, что это чисто виртуальная функция, но я начинаю сомневаться в этом (..?)
  • Функция getPerimeter () помещается в 2d класс, а getVolume () помещается в 3d класс
  • Каждый дочерний элемент формы измерения имеет getArea () и getPerimeter () или getVolume (), зависит от измерения, которое его функция рассчитывает

Вот фрагмент того, что я сделал. Чтобы сократить, я помещу 2d класс в качестве примера:

//base initiation
class Shape{
public:
virtual void print(){};
virtual void getArea(double n){};
};

//2d class which is derived from base class
class TwoDimensionalShape : public Shape{
public:
virtual void getPerimeter(double n){};
};

//The actual shape
class Circle : public TwoDimensionalShape{
protected:
double perimeter, area;
public:
void getArea(double radius){
this->area=(3.1415*radius*radius);
}
void getPerimeter(double radius){
this->perimeter=(3.1415*2*radius);
}
void print(){
cout << "Circle's perimeter: " << this->perimeter << endl;
cout << "Circle's area: " << this->area << endl;
}
Circle(){};
~Circle(){};
};

А для самого использования есть:

//setting the object as global
Shape *object;
//the class
void circle(){
Circle circle;
object=&circle;
double radius;
system("cls");
do{
cout << "Enter radius value: ";
cin >> radius; flush();
} while (radius<=0);
object->getPerimeter(radius); object->getArea(radius);
object->print(); cin.get();
}

И я думаю, что я сделал это хорошо, но нет! Список ошибок показывает:

Error   4   error C2039: 'getPerimeter' : is not a member of 'Shape'
Error   5   IntelliSense: class "Shape" has no member "getPerimeter"

Я думал об использовании броска, но у меня явно нет никакого опыта с этим.

Короче говоря, как я могу получить доступ к любому производному классу только с помощью объекта Shape * (этот объект также используется для сферы, куба, тетраэдра и т. Д.)?

постскриптум это не дубликат Что должен содержать класс TwoDimensionalShape? как он просит совершенно другую вещь

РЕДАКТИРОВАТЬ 1: Да, подписи отстой, поэтому я отредактирую свой код на рабочем столе позже, так же как и этот, поэтому, пожалуйста, продолжайте. Спасибо!

3

Решение

Итак, позвольте мне выделить то, что вы сказали:

Функции print () и getArea () помещаются в базовый класс, который
Shape. Также спрашивают, что это чисто виртуальная функция, но я
начинает сомневаться в этом (..?)

Из вашего кода вы не знаете, что такое чистый виртуальный, любой класс с чистым виртуальным становится тем, что называется абстрактным базовым классом, ключевая пометка об абстрактном базовом классе заключается в том, что вы не можете создать его экземпляр и каждый класс, который наследуется от он должен переписать эти функции, вы делаете чисто виртуальную функцию, выполняя следующие действия:

class Shape{
public:
virtual void print() = 0;
virtual double getArea() = 0;
};

Функция getPerimeter () помещается в 2d класс, а getArea () размещается в 3d класс

getArea() а также getPerimeter() Вы уверены, что это не должно быть getVolume() а также getPerimeter(), так как это будет иметь смысл посещать детские классы, исходя из вашего третьего требования. getArea() уже существует в 3-м классе, поскольку 3-й класс должен перезаписать его, как и 2-й класс.

Короче говоря, как я могу получить доступ к любому производному классу только с помощью объекта Shape * (этот объект также используется для сферы, куба, тетраэдра и т. Д.)?

Проще говоря, вы не как ваш Shape* не будет иметь представления о том, что getPerimeter() есть или что getVolume() так как они не были определены в базовом классе. У вас есть возможность использовать временный TwoDimensionalShape* и динамически приводить объект к нему, а затем использовать этот временный указатель для получения периметра.

Подобно:

TwoDimensionalShape* ptr_shape = dynamic_cast<TwoDimensionShape*>(object);
if(ptr_shape)
{
ptr_shape->getPerimeter(/*arguments here if you have them...*/)
}
1

Другие решения

Как я могу получить доступ к любому виду производного класса только с помощью объекта Shape *

Ты не можешь Если вы знаете, что что-то является двумерной формой, вы должны получить к нему доступ через такой интерфейс (не имеет значения, действительно ли вы выскочил &circle в указатель 2D-формы или опустить Shape указатель, в данном конкретном примере, по крайней мере). База Shape класс не имеет getPerimeter функционировать и правильно не позволит вам его использовать.

2

Вам нужно сделать безопасное снижение, используйте dynamic_cast.

TwoDimensionalShape* shape_eddge = dynamic_cast<TwoDimensionalShape*>(circle);
if (shape_eddge)
shape_eddge->getPerimeter()

http://en.cppreference.com/w/cpp/language/dynamic_cast

0

Прежде всего, если ваш базовый класс абстрактный, ваши методы должны выглядеть следующим образом:

class Shape {
public:
virtual void print() = 0;
virtual double getArea() = 0;
};

Тогда у дочернего класса может быть свой собственный чистый виртуальный метод.

getVolume или же getPerimeter

class TwoDimensionalShape : public Shape{
public:
virtual double getArea() { return getPerimeter(); }
virtual double getPerimeter() = 0;
};

И Circle теперь может реализовать метод getPerimeter и использовать свое значение для вычисления периметра

class Circle : TwoDimensionalShape {
private:
float m_radius;

public:
virtual double getPerimeter() { return 2.0 * PI * m_radius; }
};
0
По вопросам рекламы [email protected]