正确的方法来为C++创建数据对象班级?

发布于 2025-01-23 03:32:30 字数 1716 浏览 0 评论 0原文

我正在为自己创建的小课而苦苦挣扎。它应该保存带有数据的数组,该数组必须在删除类对象时必须删除。因此:

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <math.h>    // for sin/cos
#include <algorithm> // for std::swap

class Grid
{
public:
    unsigned int dimX_inner, dimY_inner;
    double *x_vector1;
    unsigned int ghostzone;

    int dimX_total, dimY_total;

    double h_x, h_y;

    Grid(const unsigned int dimX_inner, const unsigned int dimY_inner, const unsigned int ghostzone = 0);
    ~Grid();
};

Grid::Grid(unsigned int gridsize_x, unsigned int gridsize_y, unsigned int ghostzoneWidth) : dimX_inner(gridsize_x),
                                                                                            dimY_inner(gridsize_y),
                                                                                            x_vector1(new double[(gridsize_x + 2 * ghostzoneWidth) * (gridsize_y + 2 * ghostzoneWidth)])

{
    ghostzone = ghostzoneWidth;
    dimX_total = gridsize_x + 2 * ghostzoneWidth;
    dimY_total = gridsize_y + 2 * ghostzoneWidth;
    h_x = (double)1.0 / (gridsize_x - 1);
    h_y = (double)1.0 / (gridsize_y - 1);
}
Grid::~Grid()
{
    delete[] x_vector1;
}

这就是我现在需要的。添加了一点主:

int main()
{
    int problemsize = 5;

    Grid *grid1 = new Grid(problemsize, problemsize);

    delete[] grid1;

    return 0;
}

我之前写过类似的班级,没有问题。当然,其中大部分是从一些在线练习/示例中获取的。 但是在这种情况下,在运行程序时(在删除行)运行程序时会得到细分故障。我猜是构造函数,以某种方式构成了问题。我想问什么:

  1. 造成细分故障的原因是什么?
  2. 代码中的构造函数是否可接受”(编码样式)?
  3. 将另一个数据对象添加到类(例如数组 *x_vector2)时,我是否需要提出任何其他注意事项?

简短说明:我正在使用WSL进行此操作(不知道这是否相关)

I'm struggling with a small class I created. It is supposed to hold an array with data, that has to be deleted when the class object is deleted. Hence:

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <math.h>    // for sin/cos
#include <algorithm> // for std::swap

class Grid
{
public:
    unsigned int dimX_inner, dimY_inner;
    double *x_vector1;
    unsigned int ghostzone;

    int dimX_total, dimY_total;

    double h_x, h_y;

    Grid(const unsigned int dimX_inner, const unsigned int dimY_inner, const unsigned int ghostzone = 0);
    ~Grid();
};

Grid::Grid(unsigned int gridsize_x, unsigned int gridsize_y, unsigned int ghostzoneWidth) : dimX_inner(gridsize_x),
                                                                                            dimY_inner(gridsize_y),
                                                                                            x_vector1(new double[(gridsize_x + 2 * ghostzoneWidth) * (gridsize_y + 2 * ghostzoneWidth)])

{
    ghostzone = ghostzoneWidth;
    dimX_total = gridsize_x + 2 * ghostzoneWidth;
    dimY_total = gridsize_y + 2 * ghostzoneWidth;
    h_x = (double)1.0 / (gridsize_x - 1);
    h_y = (double)1.0 / (gridsize_y - 1);
}
Grid::~Grid()
{
    delete[] x_vector1;
}

That's all I need for now. Added a little main:

int main()
{
    int problemsize = 5;

    Grid *grid1 = new Grid(problemsize, problemsize);

    delete[] grid1;

    return 0;
}

I've written a similar class before, that ran without problems. Granted most of it was taken from some online exercises/examples.
But in this case I get a Segmentation fault when running the program (at the delete line). I guess it's the constructor, that somehow constitutes the problem. What I'd like to ask:

  1. What might be the cause of the segmentation fault?
  2. Is the constructor in the code "acceptable" (coding style wise)?
  3. Would I have to make any additional considerations when adding another data object to the class (e.g. an array *x_vector2)?

Short remark: I'm running this using WSL (don't know whether this is relevant)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷路的信 2025-01-30 03:32:30

可能导致分割故障的原因是什么?

您不能delete []您通过new创建的内容。 新的/新[]必须与其各自的计数器零件delete/delete []匹配。混合它们会导致不确定的行为。实际上,您应该在可能的情况下避免使用新的删除。例如,您的main应该看起来像这样:

int main()
{
    int problemsize = 5;    
    Grid grid1{problemsize, problemsize};
}

grid1的删除器将在范围范围内被调用。

代码中的构造函数是“可接受”(明智的编码样式)?

否。您为某些成员使用成员初始化列表,但是为什么不为所有成员呢?对于基本类型,差异可以忽略不计,但是在样式方面,您应该始终更喜欢初始化而不是初始化以及在构造体主体中的分配。

在将另一个数据对象添加到类(例如array *x_vector2)?

时,我是否需要提出任何其他注意事项

您无需添加另一个成员。该类由于忽略了3/5的规则( https:// en .cppReference.com/w/cpp/langue/rule_of_three )。您应该将其委派给容器和/或智能指针,而不是手动管理内存。在您的情况下,std :: vector似乎很合适。然后可以为destructor为〜grid()=默认值;(参见零的规则)。

管理资源已经足以让班级做。因此,做某件事的类不应加上内存。在极罕见的情况下,您需要编写一种管理内存的自定义类型,但是在大多数情况下,标准容器或智能指针就足够了。

What might be the cause of the segmentation fault?

You cannot delete[] what you created via new. new / new[] must be matched with their respective counter part delete / delete[]. Mixing them results in undefined behavior. Actually you should avoid any use of new or delete when possible. For example your main should look like this:

int main()
{
    int problemsize = 5;    
    Grid grid1{problemsize, problemsize};
}

The destructor of grid1 will be called when it goes out of scope.

Is the constructor in the code "acceptable" (coding style wise)?

No. You use the member initializer list for some members, but why not for all? For fundamental types the difference is negligible, but style-wise you should always prefer initialization rather than initialization plus assignment in the constructor body.

Would I have to make any additional considerations when adding another data object to the class (e.g. an array *x_vector2)?

You need not add another member. The class is already broken due to ignoring the rule of 3/5 (https://en.cppreference.com/w/cpp/language/rule_of_three). Instead of manually managing the memory you should delegate that to containers and/or smart pointers. In your case a std::vector seems to fit. The destructor can then be ~Grid() = default; (cf. rule of zero).

Managing a resource is already enough for a class to do. Consequently a class that does something should not in addition manage memory. In extremely rare cases you need to write a custom type that manages memory, but most of the time a standard container or a smart pointer should suffice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文