簡體   English   中英

如何聲明指向類對象的指針向量?

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

問題是我正在努力制作類Shape 的對象。 我聲明了向量,但不知道如何將它連接到類Shape及其對象。 代碼本身有一個基類,它是Shape ,然后是兩個子類CircleRectancle 代碼的思路是在main函數中使用一個vector,對於Circle區域和Rectangle區域有多種情況。 這是代碼:

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

你想要多態性 您只需使用圓形或矩形的構造函數,例如:

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

但是,您需要刪除基類中純虛方法的定義,因為它在 class 內部,並且只聲明它。

然后,您需要使用完全相同的原型來實現該方法,因此您也需要將 Circle 中的方法標記為const 對於 Rectangle 類也是如此,您在其中也輸入了錯誤,因為該方法的名稱是“GetArea”,而不是“getArea”。


完整的最小工作示例:

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

輸出:

形狀面積 = 3.14 形狀面積 = 6

其中第一個區域來自圓形,第二個區域來自矩形。

我建議您閱讀: 多態類中的虛擬析構函數C++ 中的“覆蓋”關鍵字用於什么?


在練習完所有這些之后,您應該真正開始使用智能指針,例如std::vector<std::unique_ptr<Shape>> shape; , 而不是原始指針。 這樣,您就不必擔心刪除手動動態分配的內存。

首先,類 Shape 必須有一個虛擬析構函數

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

    }

    virtual ~Shape() = default;
};

在類中,成員函數GetArea用限定符 const 聲明。 所以在派生類中,覆蓋函數也應該有限定符 const。

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

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

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

而不是類型的向量

std::vector<Shape *> shape;

你可以使用std::unique_ptr<Shape>的向量。 例如

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

在這種情況下,您不需要手動刪除指針,例如使用標准算法std::for_each作為向量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM