繁体   English   中英

指向C ++中的指针初始化的图像指针

[英]image pointer to pointer initialization in C++

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

我有这样的课:

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装饰,该怎么办? 有什么办法吗? 谢谢。

这不是复制构造函数

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

这是一个复制构造函数

MyImage(const MyImage &image)

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

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

在您的情况下, wh为常量没有错。 您可以通过以下方式编写构造函数:

 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));
     }
 }

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

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实例,则wh不能为const。

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

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]; }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM