在 C++ 中的数组中存储抽象基础 class 的不同派生 classes 的对象
Storing objects of different derived classes of an abstract base class in an array in C++
我是一个尝试学习 C++ 的初学者。所以,这个问题听起来很陈词滥调。请帮助我了解我哪里出错了。
问题描述如下。
Objective :
- 定义一个抽象的 class 形状作为接口。 (使用纯虚函数)
- 覆盖派生的 classes 矩形、圆形、三角形中的方法。
- 需要两个函数- a。 read() -> 读取特定形状的输入参数(测量值)。
b. area() -> 计算形状的总面积。
- 将不同派生的 classes 的对象(或指向对象的指针)存储在一个数组中。
- 计算每个数组成员的面积。
- 计算总面积。
代码片段:
shape.hpp - 基础 class 头文件。
namespace generalShape
{
class Shape {
public :
virtual void read() = 0;
virtual double area() = 0 ;
};
}
rect.hpp - 派生的 class 头文件。
namespace rect2D
{
class Rectangle {
private :
double length;
double breadth;
public :
void read();
double area() ;
};
}
还为另外两个派生的 classes 编写了类似的头文件,
即 circle.hpp 和 triangle.hpp
rect.cpp - 派生的 class 实现文件。
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;
}
还为其他两个派生的 classes 编写了类似的实现文件,
即 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 尝试使用 基数组 class 指针指向派生的 class 对象不同的 classes(这是允许的,对吧?)。但它给出了一个错误。
error: cannot convert ‘rect2D::Rectangle*’ to ‘generalShape::Shape*’ in assignment
以及其他派生的 class 对象的类似错误。
所以,我尝试通过类型转换来解决这个问题。
// 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()) ;
这样做,编译无误。但是当我尝试执行时,它给出了分段错误。我不确定为什么会这样。但我认为是因为我在基础 class 头文件中定义了纯虚函数。即使是这样,我也不确定如何纠正它。
其次,在方法2中,在查看了Whosebug上的其他建议后,我尝试使用vectors来实现类似的功能。但是现在我收到一个错误。
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)
^~~~~~~~~
而且我不明白如何纠正这个问题。所以,我被困在这个问题上,无法解决it.Please帮助我理解和纠正错误。
你只是忘了说明,你的 class rect2D::Rectangle 实现了你的抽象接口 class generalShape::Shape.
您可以通过添加
: public generalShape::Shape
到 rect2D::Rectangle 的声明。
那么固定的声明是:
namespace rect2D
{
class Rectangle : public generalShape::Shape {
private :
double length;
double breadth;
public :
void read();
double area() ;
};
}
另一个提示:如果您打算通过持有基 class 指针的容器销毁对象,请在基 class generalShape::Shape 中定义一个虚拟析构函数。
我是一个尝试学习 C++ 的初学者。所以,这个问题听起来很陈词滥调。请帮助我了解我哪里出错了。
问题描述如下。
Objective :
- 定义一个抽象的 class 形状作为接口。 (使用纯虚函数)
- 覆盖派生的 classes 矩形、圆形、三角形中的方法。
- 需要两个函数- a。 read() -> 读取特定形状的输入参数(测量值)。 b. area() -> 计算形状的总面积。
- 将不同派生的 classes 的对象(或指向对象的指针)存储在一个数组中。
- 计算每个数组成员的面积。
- 计算总面积。
代码片段:
shape.hpp - 基础 class 头文件。
namespace generalShape
{
class Shape {
public :
virtual void read() = 0;
virtual double area() = 0 ;
};
}
rect.hpp - 派生的 class 头文件。
namespace rect2D
{
class Rectangle {
private :
double length;
double breadth;
public :
void read();
double area() ;
};
}
还为另外两个派生的 classes 编写了类似的头文件, 即 circle.hpp 和 triangle.hpp
rect.cpp - 派生的 class 实现文件。
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;
}
还为其他两个派生的 classes 编写了类似的实现文件, 即 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 尝试使用 基数组 class 指针指向派生的 class 对象不同的 classes(这是允许的,对吧?)。但它给出了一个错误。
error: cannot convert ‘rect2D::Rectangle*’ to ‘generalShape::Shape*’ in assignment
以及其他派生的 class 对象的类似错误。
所以,我尝试通过类型转换来解决这个问题。
// 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()) ;
这样做,编译无误。但是当我尝试执行时,它给出了分段错误。我不确定为什么会这样。但我认为是因为我在基础 class 头文件中定义了纯虚函数。即使是这样,我也不确定如何纠正它。
其次,在方法2中,在查看了Whosebug上的其他建议后,我尝试使用vectors来实现类似的功能。但是现在我收到一个错误。
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)
^~~~~~~~~
而且我不明白如何纠正这个问题。所以,我被困在这个问题上,无法解决it.Please帮助我理解和纠正错误。
你只是忘了说明,你的 class rect2D::Rectangle 实现了你的抽象接口 class generalShape::Shape.
您可以通过添加
: public generalShape::Shape
到 rect2D::Rectangle 的声明。 那么固定的声明是:
namespace rect2D
{
class Rectangle : public generalShape::Shape {
private :
double length;
double breadth;
public :
void read();
double area() ;
};
}
另一个提示:如果您打算通过持有基 class 指针的容器销毁对象,请在基 class generalShape::Shape 中定义一个虚拟析构函数。