C ++“'Shape':无法实例化抽象类”找不到问题的根源

问题描述 投票:0回答:1

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

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

c++ class inheritance multiple-inheritance
1个回答
3
投票

您无法将对象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;
© www.soinside.com 2019 - 2024. All rights reserved.