首页 > 解决方案 > C++“'Shape': 无法实例化抽象类”找不到问题的根源

问题描述

我有Shape5 个不同的类(在不同的文件中)从它继承的类。在覆盖所有不同类中的所有纯虚函数后,我得到了这个错误: '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;
};

以下是 2 个继承自的类的示例Shape

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);
    }

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

标签: c++inheritanceoverridingabstract-classmultiple-inheritance

解决方案


您不能将对象存储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;

推荐阅读