C++ "'Shape': cannot instantiate abstract class"找不到问题的根源

C++ "'Shape': cannot instantiate abstract class" can't find the source of the problem

本文关键字:问题 找不到 class cannot Shape C++ instantiate abstract      更新时间:2023-10-16

我有 5 个不同类(在不同的文件中(从它继承的类Shape。 覆盖所有不同类中的所有纯虚函数后,我收到此错误:'Shape': cannot instantiate abstract class,它不会告诉我错误来自哪里。 这是Shape类:

#pragma once
#include "Point.h"
#include "Canvas.h"
#include <string>
class Shape 
{
public:
Shape(const std::string& name, const std::string& type);
virtual double getArea() const = 0;
virtual double getPerimeter() const = 0;
virtual void draw(const Canvas& canvas) = 0;
virtual void move(const Point& other) = 0; // add the Point to all the points of shape
void printDetails() const;
std::string getType() const;
std::string getName() const;
virtual void clearDraw(const Canvas& canvas) = 0;
protected:
std::string _name;
std::string _type;
};

下面是从Shape继承的 2 个类的示例:

class Circle : public Shape
{
Point _center;
double _radius;
public:
Circle(const Point& center, double radius, const std::string& type, const std::string& name);
~Circle();
const Point& getCenter() const;
double getRadius() const;
virtual void draw(const Canvas& canvas);
virtual void clearDraw(const Canvas& canvas);
// override functions if need (virtual + pure virtual)
virtual void move(const Point& other);
virtual double getArea() const;
virtual double getPerimeter() const;
};

我怀疑问题来自这个类,在这个类中,我保持函数纯虚拟,因为从这个类中,其他类也继承了,它们需要不同的实现:

#include "Shape.h"
#include "Point.h"
#include <vector>
class Polygon : public Shape
{
public:
Polygon(const std::string& type, const std::string& name);
virtual ~Polygon();
// override functions if need (virtual + pure virtual)
virtual void move(const Point& other);
virtual double getArea() const = 0;
virtual double getPerimeter() const = 0;
virtual void draw(const Canvas& canvas) = 0;
virtual void clearDraw(const Canvas& canvas) = 0;
protected:
std::vector<Point> _points;
};

这是我认为可能发生错误的代码部分:

if (optionChosen == 0) // Circle
{
double x = 0;
double y = 0;
double radius = 1.0;
std::string name;
std::cout << "Please enter X: " << std::endl;
std::cin >> x;
std::cout << "Please enter Y: " << std::endl;
std::cin >> y;
do
{
std::cout << "Please enter radius: " << std::endl;
std::cin >> radius;
if (radius < 1)
{
std::cout << "Invalid radius... Try again" << std::endl;
}
// If radius is invalid this code will run again
} while (radius < 1);
std::cout << "Enter the name of the shape: " << std::endl;
std::cin >> name;
const Point& center = Point(x, y);
// Create a new circle and push it to the vector
Circle circle = Circle::Circle(center, radius, "Circle", name); // Circle inherits from Shape
_shapes.push_back(circle);
}
else if (optionChosen == 1) // Arrow
{
double point1[2] = { 0 };
double point2[2] = { 0 };
std::string name;
std::cout << "Enter the X of point number: 1" << std::endl;
std::cin >> point1[0];
std::cout << "Enter the Y of point number: 1" << std::endl;
std::cin >> point1[1];
std::cout << "Enter the X of point number: 2" << std::endl;
std::cin >> point2[0];
std::cout << "Enter the Y of point number: 2" << std::endl;
std::cin >> point2[1];
std::cout << "Enter the name of the shape: " << std::endl;
std::cin >> name;
const Point& Point1 = Point(point1[0], point1[1]);
const Point& Point2 = Point(point2[0], point2[1]);
// Create a new arrow and push it to the vector
Arrow arrow = Arrow::Arrow(Point1, Point2, "Arrow", name); // Arrow inherits from polygon
_shapes.push_back(arrow);
}
else if (optionChosen == 2) // Triangle
{
double point1[2] = { 0 };
double point2[2] = { 0 };
double point3[2] = { 0 };
std::string name;
std::cout << "Enter the X of point number: 1" << std::endl;
std::cin >> point1[0];
std::cout << "Enter the Y of point number: 1" << std::endl;
std::cin >> point1[1];
std::cout << "Enter the X of point number: 2" << std::endl;
std::cin >> point2[0];
std::cout << "Enter the Y of point number: 2" << std::endl;
std::cin >> point2[1];
std::cout << "Enter the X of point number: 3" << std::endl;
std::cin >> point3[0];
std::cout << "Enter the Y of point number: 3" << std::endl;
std::cin >> point3[1];
std::cout << "Enter the name of the shape: " << std::endl;
std::cin >> name;
const Point& Point1 = Point(point1[0], point1[1]);
const Point& Point2 = Point(point2[0], point2[1]);
const Point& Point3 = Point(point3[0], point3[1]);
// Create a new triangle and push it to the vector
Triangle triangle = Triangle::Triangle(Point1, Point2, Point3, "Triangle", name); // Triangle inherits from Polygon
_shapes.push_back(triangle);
}
else if (optionChosen == 3) // Rectangle
{
double topLeftCorner[2] = { 0 };
double length = 0;
double width = 0;
std::string name;
std::cout << "Enter the X of the left corner: " << std::endl;
std::cin >> topLeftCorner[0];
std::cout << "Enter the Y of the left corner: " << std::endl;
std::cin >> topLeftCorner[1];
std::cout << "Please enter the length of the shape: " << std::endl;
std::cin >> length;
std::cout << "Please enter the width of the shape: " << std::endl;
std::cin >> width;
std::cout << "Enter the name of the shape: " << std::endl;
std::cin >> name;
const Point& point = Point(topLeftCorner[0], topLeftCorner[1]);
// Create a new rectangle and push it to the vector
myShapes::Rectangle rectangle = myShapes::Rectangle(point, length, width, "Rectangle", name); // Rectangle inherits from Polygon
_shapes.push_back(rectangle);
}

如果有人能帮我找到问题,我会很高兴。

不能将对象Shape存储在向量中,因为它包含一个纯虚函数。您可以改为将指针存储在向量或智能指针中,并相应地创建子类。

std::vector<Shape*> _shapes;
//…
_shapes.push_back( new Circle( … ) );

std::vector<std::unique_ptr<Shape>> _shapes;
//…
_shapes.push_back( std::make_unique<Circle>( center, radius, "Circle", name ) );

另外,在使用继承时,我建议使用override关键字。例如,在您的 Circle 类中,您将拥有

void move(const Point& other) override;