我有一个用于加载和存储(然后删除)图像数据(像素和标题)的类。在构造函数中,我初始化数据和位图标题,如下所示:
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++(我没有用正确的搜索关键词进行搜索)所以从这篇文章我看过我应该制作复制构造函数和赋值运算符。
答案 0 :(得分:1)
在C ++中,有一个“三权规则”,基本上说,如果你有一个自定义析构函数,你也应该创建一个复制构造函数和一个复制赋值运算符。
你是正确的假设当你'按值传递'时会调用构造函数 - 但是,这是复制构造函数,而不是你提供的默认构造函数。
如果你没有定义一个,编译器会很乐意为你提供一个 - 但它会对你拥有的所有指针做一个“浅”副本 - 实质上,你的副本将指向与原始相同的内存。我想你可以理解为什么它会删除你的原文:)