gpt4 book ai didi

c++ - 为什么这个析构函数不必删除类对象?

转载 作者:行者123 更新时间:2023-11-30 03:35:10 28 4
gpt4 key购买 nike

我是编程和学习类(class)的初学者。我正在关注 archived online course并为 class Polygon 创建析构函数。

answer given~Polygon 没有删除 PointArray 点 的行,只包含减少 numPolygons 的行。我假设 ~PointArray 以某种方式被激活以删除 points

  • 为什么我们不必在 ~Polygondelete[] &points;

  • 如果我的假设是正确的,PointArray 的析构函数何时以及如何生效?

  • delete[] &points;~Polygon 中对程序有何影响?

以下简化代码在 Visual Studio Community 2015 下编译。

谢谢!

class Point {
private: int x, y;
public:
Point(int x = 0, int y = 0) {
this->x = x; // initializes (*this).x with x
this->y = y; // initializes (*this).y with x
}
// other member functions...
};

class PointArray {
int len;
Point *points;
public:
PointArray() {
len = 0;
points = new Point[0];
}
PointArray(const Point copyPoints[], const int size) {
points = new Point[size];
len = size;
for (int i = 0; i < size; ++i) points[i] = copyPoints[i];
}
PointArray(const PointArray &pv) {
len = pv.len;
points = new Point[len];
for (int i = 0; i < len; ++i) points[i] = pv.points[i];
}
~PointArray() {
delete[] points;
}
// other member functions...
};

class Polygon {
protected:
PointArray points;
static int numPolygons; // tracks # of Polygon instances/objects
public:
Polygon(const Point pointArr[], const int numPoints)
: points(pointArr, numPoints) { // initializes internal PointArray
++numPolygons; // +1 (initialized)
}
Polygon(const PointArray &pa)
: points(pa) { // initializes internal PointArray with arg
++numPolygons;
}
~Polygon() {
//delete[] &points;
--numPolygons;
}
};

int main() { return 0; }

最佳答案

你的假设基本正确。这里有一些注意事项:

  • delete (和 delete[] )仅用于删除指向堆上分配的变量的指针,使用 new运算符(operator)。在Polygon类,PointArray member 不是指针,它只是一个完全包含在 Polygon 中的成员对象对象。

  • 你是对的,PointArray 的析构函数负责删除Point *points PointArray 中的数组类(class)。发生的事情是,当调用“父”对象(如 Polygon)的析构函数时,它会自动递归地为其所有成员对象(以及所有它们的成员对象,等)这是来自 cppreference 的相关部分:

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

所以,在这个简单的例子中,顺序是:

  1. ~Polygon调用析构函数并完全执行,递减 numPolygons .
  2. ~PointArraypoints 上调用了析构函数.这将删除 PointArray 拥有的基础数组对象。

如果您要删除 PointArray.points ~Polygon 中的指针,数组将被删除两次(一次被 ~Polygon 和一次被 ~PointArray ),这是未定义的行为,但可能会导致崩溃。

编辑添加:作为进一步的评论,在现代 C++ 中,您可能希望使用像 std::unique_ptr 这样的“智能指针” ,而不是像您的教程那样使用“原始”指针。这将您从这种低级内存管理的负担中解放出来,因为智能指针类将处理超出范围时删除数组的所有细节。

第二次编辑:@user4581301 有一个更好的建议,即使用 std::vector 而不是用指针打扰。 vector类将为您处理所有底层内存管理细节。它还会动态增长和收缩以处理可变大小的对象数组,而不是被限制为固定大小。

关于c++ - 为什么这个析构函数不必删除类对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41455263/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com