2013-04-24 3 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 
    } 

однако, если вес и h- const, кажется, что w и h должны быть инициализированы в списке инициализации, как показано ниже:

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

то я не могу d elete, потому что w изменяется перед ним. Мой вопрос: что мне делать, если я не хочу исключать конструкцию const в w и h? Любой метод? Благодарю.

+0

' Кажется, что ...', к сожалению, это утверждение неверно. Никакой конструктор никогда не должен удалять то, что уже существует, потому что все конструкторы начинаются с неинициализированных объектов. Ваша проблема - это что-то другое. Отправьте еще один код. – john

+0

Этот код является абсолютно неправильным. 'image' всегда будет недопустимым указателем, и вы попытаетесь удалить что-то, чего там нет. – Gorpik

+0

это конструктор копирования? :) –

ответ

0

Это не копия-конструктор

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

Это копия-конструктор

MyImage(const MyImage &image) 

Не используйте : w(_w) и сначала удалите предыдущее изображение, а затем использовать w = image._w.

Однако вам не нужно ничего удалять, потому что это конструктор.

+1

он не может использовать ш = _w –

+0

@WilmerEHenaoH: Опечатка исправлена, благодаря – deepmax

0

В вашем случае нет ничего плохого в том, что w и 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)); 
    } 
} 

Из моего опыта обработки изображений, рекомендуется хранить изображение в виде одной таблицы, строка за строкой. Вы можете получить доступ к (х, у) -й элемент с помощью вызова 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 
} 

Если вам нужно присвойте подобный метод, который копирует содержимое некоторым образа (либо хранящиеся в беззнаковом INT * или в другом классе изображения) до существующих экземпляра изображения, w и h не могут быть Уст.

+0

я не думаю, что это какое-либо решение. – john

+0

Что такое 'data'? В любом случае, что бы это ни было, в конструкторе он не инициализирован, поэтому при попытке удалить его вы столкнетесь с неопределенным поведением. – Gorpik

+0

Да, не заметили, что он написал конструктор, я догадался, косвенно, что он хотел бы написать метод присвой тип, который на самом деле должен был бы удалить предыдущий экземпляр данных изображения. – Spook

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]; } 
}; 
Смежные вопросы