在析构函数中删除[]并将类对象传递给函数作为参数

时间:2013-12-11 21:07:15

标签: c++ memory-management c++11 destructor pass-by-value

我有一个用于加载和存储(然后删除)图像数据(像素和标题)的类。在构造函数中,我初始化数据和位图标题,如下所示:

IMAGE_DATA::IMAGE_DATA():data(0)
{
    memset(&fileheader,0,(sizeof(BITMAPFILEHEADER)));
    memset(&infoheader,0,(sizeof(BITMAPINFOHEADER)));
};

并且数据是在加载函数中使用unsigned char*分配的new[...]数组。 析构函数:

IMAGE_DATA::~IMAGE_DATA()
{
    freeData();
};

void IMAGE_DATA::freeData()
{
    delete[] data;

    memset (&fileheader, 0, sizeof(fileheader));
    memset (&infoheader, 0, sizeof(infoheader));
};

现在的问题是,在过滤类中,我在将数据作为参数加载后传递了类对象:

IMAGE_DATA image;

image.load("filename"); //load headers and pixel data

FILTER filter;

filter.scale(image,scalefactor,"outputfilename");  //scales the image and write to a .bmp

这是我的代码的缩短版本。因此,IMAGE_DATA ::load运行平稳,但是当代码到达缩放函数时,我得到以下断言失败:

Debug Assertion Failed!
....
Expression:
_BLOCK_TYPE_IS_VALID(pHeap->nBlockUse)
....
第52行的 crt \ src \ dbgdel.cpp

这是因为我制作了析构函数。为了好奇,我更改了参数,所以我将它们作为参考传递。

/*FILTER::*/scale(IMAGE_DATA& /*passed as reference*/, unsigned short, const char*); 

这现在有效。如果我传递'by value',似乎析构函数被调用,但构造函数也应该,并且应该没有问题,因为在构造函数中我初始化了所有内容。

我想通过值传递它,因为我想保持原始状态不变,我只想使用它的数据。

如何在不传递参考的情况下使其工作,以及它与传递值的方式有何不同,因为值似乎更“安全”。

编辑:我刚刚发现了一篇关于此事的帖子:Side effects when passing objects to function in C++(我没有用正确的搜索关键词进行搜索)所以从这篇文章我看过我应该制作复制构造函数和赋值运算符。

1 个答案:

答案 0 :(得分:1)

在C ++中,有一个“三权规则”,基本上说,如果你有一个自定义析构函数,你也应该创建一个复制构造函数和一个复制赋值运算符。

你是正确的假设当你'按值传递'时会调用构造函数 - 但是,这是复制构造函数,而不是你提供的默认构造函数。

如果你没有定义一个,编译器会很乐意为你提供一个 - 但它会对你拥有的所有指针做一个“浅”副本 - 实质上,你的副本将指向与原始相同的内存。我想你可以理解为什么它会删除你的原文:)