Image类的析构函数和重载=运算符

时间:2014-12-08 19:18:34

标签: c++ class destructor

我是C ++的新手。我的图像处理有问题。我想要做的是编写我的类Image,它具有私有变量水平和垂直大小的图像和每个像素的数据(灰度,只是浮点数的二维数组)。我还在类中编写了基本函数:getPixel,SetPixel,GetSize,GetData(返回2D数据数组)。

我的问题是:我读过,为了获得最佳性能,我必须编写一个析构函数并重载#34; ="至少是运营商。

1)有人可以解释为什么我真的需要它(只要这个版本工作或多或少)。

2)你能写下析构函数和" ="我的运营商?我想,对于专家来说并不困难,我尝试了一次但是我的析构函数出现了内存错误:错误_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse);

更新:即使是现在,也没有定义" ="运算符,我可以在我的main函数中使用它。如果,比方说,我有大小(1x1)的图像img1和大小(2x2)的img2,我可以写img1 = img2,它可以工作!

Update2:在我尝试实现简单的析构函数(delete [] 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;
}

仍有内存错误:&#34; _BLOCK_TYPE_IS_VALID ...&#34;

2 个答案:

答案 0 :(得分:0)

你问:

  

1)有人可以解释为什么我真的需要它(只要这个版本工作或多或少)。

您正在构造函数中为pix分配内存。您需要实现一个释放内存的析构函数。我没有看到你班上实施的一个。

~Image()
{
   delete [] pix;
}

只要在析构函数中添加代码以释放类在其生命周期的某个时刻获取的资源,The Rule of Three就会发挥作用,您必须实现复制构造函数,无错代码的赋值运算符。

赋值运算符将类似于:

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 :(得分:0)

  

1)有人可以解释为什么我真的需要它(只要这个版本工作或多或少)。

这里已经回答:https://stackoverflow.com/a/4172724/2642059 与您相关的细分是:

  

大多数情况下,您不需要自己管理资源,因为现有的类(如std :: string)已经为您完成了。只需将使用std :: string成员的简单代码与使用char *的复杂且容易出错的替代方法进行比较,您应该确信。 只要您远离原始指针成员,三个规则就不太可能涉及您自己的代码。

作为一个新的C ++编码器,我能为你做的最好的事情是引导你远离原始指针

  

2)你能写下析构函数和&#34; =&#34;我的运营商?我想,对于专家来说并不困难,我尝试了一次,但是我的析构函数出现了内存错误:错误_BLOCK_TYPE_IS_VALID(pHead-&gt; 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
    }
};