正确的方法来为C++创建数据对象班级?
我正在为自己创建的小课而苦苦挣扎。它应该保存带有数据的数组,该数组必须在删除类对象时必须删除。因此:
#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;
}
我之前写过类似的班级,没有问题。当然,其中大部分是从一些在线练习/示例中获取的。 但是在这种情况下,在运行程序时(在删除行)运行程序时会得到细分故障。我猜是构造函数,以某种方式构成了问题。我想问什么:
- 造成细分故障的原因是什么?
- 代码中的构造函数是否可接受”(编码样式)?
- 将另一个数据对象添加到类(例如数组 *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:
- What might be the cause of the segmentation fault?
- Is the constructor in the code "acceptable" (coding style wise)?
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能
delete []
您通过new
创建的内容。新的
/新[]
必须与其各自的计数器零件delete
/delete []
匹配。混合它们会导致不确定的行为。实际上,您应该在可能的情况下避免使用新的
或删除
。例如,您的main
应该看起来像这样:grid1
的删除器将在范围范围内被调用。否。您为某些成员使用成员初始化列表,但是为什么不为所有成员呢?对于基本类型,差异可以忽略不计,但是在样式方面,您应该始终更喜欢初始化而不是初始化以及在构造体主体中的分配。
您无需添加另一个成员。该类由于忽略了3/5的规则( https:// en .cppReference.com/w/cpp/langue/rule_of_three )。您应该将其委派给容器和/或智能指针,而不是手动管理内存。在您的情况下,
std :: vector
似乎很合适。然后可以为destructor为〜grid()=默认值;
(参见零的规则)。管理资源已经足以让班级做。因此,做某件事的类不应加上内存。在极罕见的情况下,您需要编写一种管理内存的自定义类型,但是在大多数情况下,标准容器或智能指针就足够了。
You cannot
delete[]
what you created vianew
.new
/new[]
must be matched with their respective counter partdelete
/delete[]
. Mixing them results in undefined behavior. Actually you should avoid any use ofnew
ordelete
when possible. For example yourmain
should look like this:The destructor of
grid1
will be called when it goes out of scope.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.
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.