图像类的析构函数和重载 = 运算符
Destructor and overloaded= operator for Image class
我是C++新手。我在图像处理方面有问题。我正在尝试做的是编写我的类 Image,它具有图像的水平和垂直大小以及每个像素的数据(灰度,只是浮点数的 2D 数组(作为私有变量。我还在类中编写了基本函数:getPixel,SetPixel,GetSize,GetData(返回2D数据数组(。
我的问题是:我读到,为了获得最佳性能,我必须至少编写一个析构函数和重载的"="运算符。
1(有人可以解释为什么我真的需要它(只要这个版本或多或少地工作(。
2(你能为我写析构函数和"="运算符吗?我想,这对专家来说并不难,我尝试过一次,但使用我的析构函数我遇到了内存错误:错误_BLOCK_TYPE_IS_VALID(pHead->nBlockUse(;
更新:即使是现在,无需定义"="运算符,我也可以在我的主函数中使用它。如果,比如说,我有大小 (1x1( 的图像 img1 和大小 (2x2( 的 img2,我可以写 img1=img2,它可以工作!
更新2:在我尝试实现简单的析构函数(删除[] pix(后,出现错误"_BLOCK_TYPE_IS_VALID">
struct Pixel
{
float p;
};
struct size
{
int x;
int y;
};
class Image {
private:
int _x, _y;
Pixel *pix;
public:
Image(int x, int y){
pix = new Pixel[x * y];
_x = x;
_y = y;
}
float getPixel(int i, int j) {
return pix[i * _y + j].p;
}
void setPixel(int i, int j, Pixel val)
{
pix[i * _y + j].p = val.p;
}
size GetSize(){
size a;
a.x = _x;
a.y = _y;
return a;
}
Pixel **GetData(){
Pixel **a=0;
a = new Pixel*[_x];
for (int i = 0; i < _x; i++){
a[i] = new Pixel[_y];
for (int j = 0; j < _y; j++){
a[i][j] = pix[i*_y + j];
}
}
return a;
}
};
更新日期 3:我试图实现三法则中的所有内容。我补充说:
~Image()
{
delete[] pix;
}
Image(const Image& that)
{
pix = new Pixel[that._x*that._y];
pix = that.pix;
_x = that._x;
_y = that._y;
}
Image& operator=(const Image& that)
{
if (this != &that)
{
delete[] pix;
pix = new Pixel[that._x*that._y];
pix = that.pix;
_x = that._x;
_y = that._y;
}
return *this;
}
仍然出现内存错误:"_BLOCK_TYPE_IS_VALID...">
你问:
1(有人可以解释为什么我真的需要它(只要这个版本或多或少地工作(。
您正在为构造函数中的pix
分配内存。您需要实现一个解除分配内存的析构函数。我没有看到在您的类中实现一个。
~Image()
{
delete [] pix;
}
一旦您在析构函数中添加代码以释放类在其生命周期中的某个时间点获取的资源,三法就会发挥作用,您必须为无错误代码实现复制构造函数和赋值运算符。
赋值运算符将如下所示:
Image& operator=(Image const& rhs) {
// Don't do anything for self assignment, such as a = a;
if ( this != &rhs )
{
delete [] pix;
_x = rhs._x;
_y = rhs._y;
pix = new Pixel[_x * _y];
for ( int i = 0; i < _x*_y; ++i )
{
pix[i] = rhs.pix[i]
}
}
return *this;
}
1(有人可以解释为什么我真的需要它(只要这个版本或多或少地工作(。
这里已经回答了:https://stackoverflow.com/a/4172724/2642059与您相关的细分是:
大多数情况下,您不需要自己管理资源,因为现有的类(如 std::string(已经为您完成了这项工作。只需将使用 std::string 成员的简单代码与使用 char* 的复杂且容易出错的替代代码进行比较,您应该会被说服。只要你远离原始指针成员,三法则就不太可能与你自己的代码有关。
作为一名新的C++程序员,我能为你做的最好的事情就是引导你远离原始指针。
2(你能为我写析构函数和"="运算符吗?我想,这对专家来说并不难,我尝试过一次,但使用我的析构函数我遇到了内存错误:错误_BLOCK_TYPE_IS_VALID(pHead->nBlockUse(;
R Sahu的回答在这方面做得很好。但我建议你去掉你的原始指针,所以我会告诉你如何做到这一点:
struct Pixel
{
Pixel() : p(0.0f) {} // Create a default constructor for Pixel so it can be used in a vector
float p;
};
class Image {
private:
int _x, _y;
std::vector<Pixel> pix; // This is your new array
public:
Image(int x, int y) :
pix(x * y) // This is called the constructor initializer list and that's where you construct member objects.
{
_x = x;
_y = y;
}
float getPixel(int i, int j) {
return pix[i * _y + j].p;
}
void setPixel(int i, int j, Pixel val)
{
pix[i * _y + j].p = val.p;
}
size GetSize(){
size a;
a.x = _x;
a.y = _y;
return a;
}
const Pixel* GetData(){ // We're going to pass back the vector's internal array here, but you should probably just return a const vector
return pix.data(); // We're returning this as read only data for convenience any modification to the data should be done through the Image class
}
};
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用