Меня попросили реализовать эту диаграмму в полиморфизме, который выводится для расчета геометрии:
Критерии следующие:
Вот фрагмент того, что я сделал. Чтобы сократить, я помещу 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: Да, подписи отстой, поэтому я отредактирую свой код на рабочем столе позже, так же как и этот, поэтому, пожалуйста, продолжайте. Спасибо!
Итак, позвольте мне выделить то, что вы сказали:
Функции 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...*/)
}
Как я могу получить доступ к любому виду производного класса только с помощью объекта Shape *
Ты не можешь Если вы знаете, что что-то является двумерной формой, вы должны получить к нему доступ через такой интерфейс (не имеет значения, действительно ли вы выскочил &circle
в указатель 2D-формы или опустить Shape
указатель, в данном конкретном примере, по крайней мере). База Shape
класс не имеет getPerimeter
функционировать и правильно не позволит вам его использовать.
Вам нужно сделать безопасное снижение, используйте dynamic_cast.
TwoDimensionalShape* shape_eddge = dynamic_cast<TwoDimensionalShape*>(circle);
if (shape_eddge)
shape_eddge->getPerimeter()
Прежде всего, если ваш базовый класс абстрактный, ваши методы должны выглядеть следующим образом:
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; }
};