简体   繁体   English

如何声明指向类对象的指针向量?

[英]How to declare a vector of pointers to objects of a class?

The thing is that I am struggling with making objects of the class Shape .问题是我正在努力制作类Shape 的对象。 I declare the vector, but then do not know how to connect it to the class Shape and its objects.我声明了向量,但不知道如何将它连接到类Shape及其对象。 The code itself has one base class, which is Shape and then two subclasses Circle and Rectancle .代码本身有一个基类,它是Shape ,然后是两个子类CircleRectancle The idea of the code is to use a vector in the main function, and have multiple cases for the Circle area and the Rectangle area.代码的思路是在main函数中使用一个vector,对于Circle区域和Rectangle区域有多种情况。 This is the code:这是代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Shape
{
public:
    virtual double GetArea() const = 0
    {

    }

private:

};

class Circle : public Shape
{
public:
    Circle(double p, double r) // constructor
    {
        pi = p;
        radius = r;
    }

    Circle() : pi(3.14), radius(0) {} // default constructor

    void SetRadius(double value)
    {
        radius = value;
    }

    double GetRadius() const
    {
        return radius;
    }

    double GetArea()
    {
        double area = pi * radius * radius;
        return area;
    }

private:
    double pi = 3.14;
    double radius;
};

class Rectangle : public Shape
{
public:
    Rectangle(double a, double b) // constructor
    {
        sideA = a;
        sideB = b;
    }

    Rectangle() : sideA(0), sideB(0) {} // default constructor

    void SetSideA(double value)
    {
        sideA = value;
    }

    double getSideA() const
    {
        return sideA;
    }

    void SetSideB(double val)
    {
        sideB = val;
    }

    double getSideB() const
    {
        return sideB;
    }

    double getArea()
    {
        double Area = sideA * sideB;
        return Area;
    }

private:
    double sideA;
    double sideB;
};

int main()
{
    vector<Shape*> shape;
    return 0;
}

You want Polymorphism .你想要多态性 You just use the constructor of the circle or the rectangle, for example:您只需使用圆形或矩形的构造函数,例如:

vector<Shape*> shape(1);
if(/* case is circle*/)
  shape[0] = new Circle();
else
  shape[0] = new Rectangle();

However, you need remove the definition of the pure virtual method in the base class, since it's inside the class , and only declare it.但是,您需要删除基类中纯虚方法的定义,因为它在 class 内部,并且只声明它。

Then, you need to implement that method, by using exactly the same prototype, so you need to mark the method in Circle as const too.然后,您需要使用完全相同的原型来实现该方法,因此您也需要将 Circle 中的方法标记为const Same for Rectangle class, where you also did a typo, since the name of the method is "GetArea", not "getArea".对于 Rectangle 类也是如此,您在其中也输入了错误,因为该方法的名称是“GetArea”,而不是“getArea”。


Complete Minimal Working Example:完整的最小工作示例:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Shape
{
public:
    virtual double GetArea() const = 0;
    virtual ~Shape() {};
};

class Circle : public Shape
{
public:
    Circle(double p, double r) // constructor
    {
        pi = p;
        radius = r;
    }

    Circle() : pi(3.14), radius(0) {} // default constructor

    void SetRadius(double value)
    {
        radius = value;
    }

    double GetRadius() const
    {
        return radius;
    }

    double GetArea() const
    {
        double area = pi * radius * radius;
        return area;
    }

private:
    double pi = 3.14;
    double radius;
};

class Rectangle : public Shape
{
public:
    Rectangle(double a, double b) // constructor
    {
        sideA = a;
        sideB = b;
    }

    Rectangle() : sideA(0), sideB(0) {} // default constructor

    void SetSideA(double value)
    {
        sideA = value;
    }

    double getSideA() const
    {
        return sideA;
    }

    void SetSideB(double val)
    {
        sideB = val;
    }

    double getSideB() const
    {
        return sideB;
    }

    double GetArea() const
    {
        double Area = sideA * sideB;
        return Area;
    }

private:
    double sideA;
    double sideB;
};

int main()
{
    vector<Shape*> shape(2);
    shape[0] = new Circle(3.14, 1);
    shape[1] = new Rectangle(2, 3);

    for(auto s : shape)
      std::cout << "Shape area = " << s->GetArea() << endl;

    // When you are done, delete the dynamically allocated memory.
    // You can use smart pointers in order to avoid doing this manually (and maybe forget!)
    delete shape[0];
    delete shape[1];
    return 0;
}

Output:输出:

Shape area = 3.14 Shape area = 6形状面积 = 3.14 形状面积 = 6

where the first area is from the circle, and the second area from the rectangle.其中第一个区域来自圆形,第二个区域来自矩形。

I suggest you read: Virtual destructor in polymorphic classes and What is the 'override' keyword in C++ used for?我建议您阅读: 多态类中的虚拟析构函数C++ 中的“覆盖”关键字用于什么?


After doing all this for practice, you should really start using smart pointers , like this for instance std::vector<std::unique_ptr<Shape>> shape;在练习完所有这些之后,您应该真正开始使用智能指针,例如std::vector<std::unique_ptr<Shape>> shape; , instead of raw pointers. , 而不是原始指针。 This way, you won't have to worry about deleting manually dynamically allocated memory.这样,您就不必担心删除手动动态分配的内存。

For starters the class Shape must have a virtual destructor首先,类 Shape 必须有一个虚拟析构函数

class Shape
{
public:
    virtual double GetArea() const = 0
    {

    }

    virtual ~Shape() = default;
};

Within the class the member function GetArea is declared with the qualifier const.在类中,成员函数GetArea用限定符 const 声明。 So in derived classes the overriding function shall also have the qualifier const.所以在派生类中,覆盖函数也应该有限定符 const。

double GetArea() const override
{
    double area = pi * radius * radius;
    return area;
}

and

double getArea() const override
{
    double Area = sideA * sideB;
    return Area;
}

In main you can use the member function push_back to append pointers to objects, For example在 main 中,您可以使用成员函数 push_back 将指针附加到对象,例如

std::vector<Shape*> shape;

Shape *p = new Circle( 3.14, 10.0 );

shape.push_back( p );

p = new Rectangle( 10.0, 20.0 );

shape.push_back( p );

Instead of the vector of the type而不是类型的向量

std::vector<Shape *> shape;

you could use a vector of std::unique_ptr<Shape> .你可以使用std::unique_ptr<Shape>的向量。 For example例如

std::vector<std::unique_ptr<SHape>> shape;

In this case you will not need to delete the pointers manually for example by using the standard algorithm std::for_each for the vector.在这种情况下,您不需要手动删除指针,例如使用标准算法std::for_each作为向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM