1

处理图像初始化时遇到问题。

我有这样的课:

Class MyImage
{
   private: 
       unsigned int** image;
       const unsigned int w;
       const unsigned int h;
   public:
       MyImage(unsigned int** _image,unsigned int _w,
                unsigned int _h); // copy constructor
}

看来如果我使用上面的复制构造函数,我需要先删除图像,如下所示:

 MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
   {
       if (image)
       {
           for (int i = 0;i < w;++i)
               delete[] image[i];
           delete[] image;
       }

       // .. copy _image to imge
   }

但是,如果 w 和 h 是 const 成员,似乎 w 和 h 必须在初始化列表中初始化,如下所示:

   MyImage(unsigned int** _image,unsigned int _w,unsigned int _h): w(_w),h(_h)
   {
        // ..code
   }

然后我无法删除图像,因为 w 在它之前发生了变化。我的问题是,如果我不想消除 w 和 h 中的 const 装饰,我该怎么办?有什么方法吗?谢谢。

4

3 回答 3

0

这不是复制构造函数

MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)

这是一个复制构造函数

MyImage(const MyImage &image)

不要使用: w(_w)并先删除以前的图像,然后使用w = image._w.

但是,您不需要删除任何内容,因为它是构造函数。

于 2013-04-24T08:37:36.200 回答
0

在您的情况下,作为 constw并没有错。h您可以通过以下方式编写构造函数:

 MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
     : w(_w), h(_h)
 {
     // No data is allocated in the memory pointed to by image yet
     // We have to allocate it here. Remember, that copy-ctor is
     // a constructor, so it operates on newly created instance,
     // not on an existing one.

     image = new unsigned int * [h];
     for (int i = 0; i < h; i++)
     {
         image[i] = new unsigned int [w];
         memcpy(image[i], _image[h], w * sizeof(unsigned int));
     }
 }

根据我的图像处理经验,考虑将图像逐行存储为单个表。您可以通过调用访问 (x, y)-th 元素data[y * w + x];在这种情况下,您可以简化您的复制 ctor:

MyImage::MyImage(unsigned int * source, int newW, int newH)
    : w(newW), h(newH)
{
    image = new unsigned int[w * h];
    memcpy((void *)image, (void *)source, w * h * sizeof(unsigned int));
}

按照 C++ 社区对这个术语的理解,复制构造函数看起来像这样:

MyImage::MyImage(const MyImage &source) 
    : w(source.w), h(source.h)
{
    image = new unsigned int[w * h];
    memcpy((void *)image, (void *)source.image, w * h * sizeof(unsigned int));
}

请注意,当您调用构造函数时该image字段不存在,因此您不需要释放任何内容。

 // Your code
 MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
 {
     // Class is allocated into some part of memory, which might
     // have been used, so in effect this may be actually true,
     // because image may contain some rubbish data
     if (image)
     {
         // But this will result mostly likely in Access Violation
         // error, because you would try to use (free!) some random
         // data in memory.
         for (int i = 0;i < w;++i)
             delete[] image[i];
         delete[] image;
     }

     // .. copy _image to imge
}

如果您需要类似分配的方法,它将某些图像的内容(存储在 unsigned int * 或另一个 Image 类中)复制到现有的 Image 实例,w并且h不能是 const。

于 2013-04-24T08:42:11.163 回答
0

使用封装std::vector来管理图像数据。默认的复制构造函数、移动构造函数、赋值运算符、移动赋值运算符和默认析构函数都将自动为您生成并执行正确的操作。此外,通过在连续的内存块中分配图像数据并使用跨行(或列)主要顺序,这将比为每一行分配一个新的内存块更有效......

struct MyImage
{
    const size_t w, h;
    vector<int> image;

    MyImage(const vector<int>& image, size_t w, size_t h)
        : image(image)
        , w(w)
        , h(h)
    {
        assert(image.size() == w*h);
    }

    MyImage(vector<int>&& image, size_t w, size_t h)
        : image(move(image))
        , w(w)
        , h(h)
    {
        assert(image.size() == w*h);
    }

    int& pixel(size_t x, size_t y) { return image[w*y+x]; }
    int pixel(size_t x, size_t y) const { return image[w*y+x]; }
};
于 2013-04-24T08:58:19.723 回答