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

あなたの場合、 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));
     }
 }

私の画像処理の経験から、画像を 1 つのテーブルとして行ごとに格納することを検討してください。を呼び出すことで (x, y) 番目の要素にアクセスできます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 の既存のインスタンスにコピーする assign のようなメソッドが必要な場合は、constwhすることはできません。

于 2013-04-24T08:42:11.163 に答える
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

カプセル化された を使用して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 に答える