Я - полный новичок, пытающийся изучать C ++. Так что этот вопрос может звучать очень клише ». Пожалуйста, помогите мне понять, где я иду не так.
Проблема описана ниже.
Цель:
- Определите абстрактный класс Shape, который будет действовать как интерфейс. (Используйте чисто виртуальные функции)
- Переопределить методы в производных классах Rectangle, Circle, Triangle.
- Требуются две функции - а. read () -> Чтобы прочитать входные параметры (измерения) определенной формы.
б. area () -> Для расчета общей площади фигуры.
- Хранить объекты (или указатели на объекты) различных производных классов в массиве.
- Рассчитать площадь каждого элемента массива.
- Рассчитать общую площадь.
Фрагменты кода:
shape.hpp - Заголовочный файл базового класса.
namespace generalShape
{
class Shape {
public :
virtual void read() = 0;
virtual double area() = 0 ;
};
}
rect.hpp - Заголовочный файл производного класса.
namespace rect2D
{
class Rectangle {
private :
double length;
double breadth;
public :
void read();
double area() ;
};
}
Подобные заголовочные файлы также написаны для двух других производных классов,
а именно circle.hpp и triangle.hpp
rect.cpp - Файл реализации производного класса.
using namespace rect2D;
// Read data (use it in main.cpp)
void Rectangle::read(/* no args */)
{
std::cin >> length;
std::cin >> breadth;
}
// To calculate area of a rectangle object
double Rectangle::area(/* no args */)
{
return length * breadth;
}
Подобные файлы реализации также написаны для двух других производных классов,
а именно circle.cpp и triangle.cpp
main.cpp - файл клиента.
using namespace generalShape;
using namespace rect2D;
// similarly use other namespaces as required
int main()
{
int number_of_shapes; // take input from user about number of objects
double total_area = 0;
/* Method 1 */
Shape **arr;
arr = new Shape*[size];
/* Method 2 */
//vector<Shape *> arr;
for (int i = 0; i < number_of_shapes; i++)
{
// some code to ask user about type of object
if (choice == 1)//based on user input
{
arr[i] = new Rectangle(); // for method 1
//arr.push_back(new Rectangle); // for method 2
}
// similar code for other derived class object types
// Code to calculate total_area of all objects in array.
arr[i]->read();
total_area += arr[i]->area();
}
return 0;
}
В чем моя проблема?
В main.cpp я указал Метод 1 и Метод 2 в качестве строк комментариев в основной функции.
Метод 1 пытается использовать массив указателей базового класса для указания на объекты производного класса различных классов (это разрешено, верно?). Но это дает ошибку.
error: cannot convert ‘rect2D::Rectangle*’ to ‘generalShape::Shape*’ in assignment
и аналогичные ошибки для других объектов производного класса.
Итак, я попытался определить тип решения проблемы.
// Shape is the base class with virtual methods read() and area().
// Rectangle,Triangle,Circle are derived classes which override these methods.
// main.cpp uses these header files to read user input using read() for each
// derived class and then calculate area using area(). The ultimate goal is to
// calculate total area of all derived class objects stored in an array.
arr[i] = (Shape*)(new Rectangle()) ;
Это позволяет выполнить компиляцию без ошибок. Но когда я пытаюсь выполнить, это дает ошибку сегментации. Я не уверен, почему это происходит. Но я думаю, это потому, что я определил чисто виртуальные функции в заголовочном файле базового класса. Даже если это так, я не уверен, как это исправить.
Во-вторых, в Методе 2 я пытался использовать векторов для достижения аналогичной функциональности после просмотра других предложений по stackoverflow. Но сейчас я получаю сообщение об ошибке.
error: no matching function for call to ‘std::vector<generalShape::Shape*>::push_back(rect2D::Rectangle*)’
arr.push_back(new Rectangle);
^
In file included from /usr/include/c++/7/vector:64:0,
from src/main.cpp:2:
/usr/include/c++/7/bits/stl_vector.h:939:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = generalShape::Shape*;
_Alloc = std::allocator<generalShape::Shape*>; std::vector<_Tp, _Alloc>::value_type = generalShape::Shape*]
push_back(const value_type& __x)
^~~~~~~~~
/usr/include/c++/7/bits/stl_vector.h:939:7: note: no known conversion for argument 1 from ‘rect2D::Rectangle*’ to ‘generalShape::Shape* const&’
/usr/include/c++/7/bits/stl_vector.h:953:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = generalShape::Shape*; _Alloc = std::allocator<generalShape::Shape*>; std::vector<_Tp, _Alloc>::value_type = generalShape::Shape*]
push_back(value_type&& __x)
^~~~~~~~~
И я не могу понять, как это исправить. Итак, я застрял в этой проблеме и не могу ее решить. Пожалуйста, помогите мне разобраться и исправить ошибки.