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

How to declare a vector of pointers to objects of a class?

本文关键字:对象 指针 向量 何声明 声明      更新时间:2023-10-16

问题是我正在努力制作类形状的对象。我声明了向量,但不知道如何将其连接到类 Shape及其对象。代码本身有一个基类,即Shape,然后是两个子类CircleRectancle。代码的思想是在 main 函数中使用向量,并且圆形区域和矩形区域有多个情况。这是代码:

#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();

但是,您需要删除基类中纯虚拟方法的定义,因为它在类内部,并且只声明它。

然后,您需要使用完全相同的原型来实现该方法,因此您还需要在 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++中的"override"关键字是什么?


在完成所有这些练习之后,您应该真正开始使用智能指针,例如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