2013-04-24 153 views
1

我在处理图像初始化时遇到了一个问题。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 
    } 

然后我不能d因为w在它之前改变,所以请删除图片。我的问题是我应该怎么做,如果我不想消除W和H中的常量装饰?任何方法?谢谢。

+0

'好像......',不幸的是,这种说法是错误的。任何构造函数都不需要删除已有的构造函数,因为所有构造函数都以未初始化的对象开始。你的问题是别的。张贴更多的代码。 – john 2013-04-24 08:38:30

+0

这段代码是完全错误的。 'image'将永远是一个无效的指针,你会尝试删除那些不存在的东西。 – Gorpik 2013-04-24 08:42:03

+0

这是一个复制构造函数? :) – 2013-04-24 08:43:01

回答

0

这不是一个拷贝构造

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

这是一个拷贝构造

MyImage(const MyImage &image) 

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

但是,您不需要删除任何东西,因为它是一个构造函数。

+1

他不能使用w = _w – 2013-04-24 08:55:09

+0

@WilmerEHenaoH:错误更正,谢谢 – deepmax 2013-04-24 09:00:20

0

在你的情况下,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)个元素,可以简化您的拷贝构造函数:

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 
} 

如果需要的分配状的方法,一些图像中的哪拷贝内容(无论是存储在一个无符号整型*或在另一个图像类)到图像的现有例如,wh不能常量。

+0

我不认为这是任何解决方案。 – john 2013-04-24 08:44:03

+0

什么是数据?无论如何,不​​管它是什么,在构造函数中它都没有被初始化,所以当你试图删除它时你会遇到未定义的行为。 – Gorpik 2013-04-24 08:44:10

+0

是的,没有注意到,他写了一个构造函数,我间接猜测他想编写一个类似分配的方法,它实际上必须删除以前的图像数据实例。 – Spook 2013-04-24 08:56:22

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