0

Imageクラス階層の設計提案が必要です。
現在、2種類の画像があります(1つは標準画像で、もう1つは標準画像データが含まれていません)。オブジェクトに画像データ用のメモリを割り当てたい場合もあれば、オブジェクトがそれを指すようにしたい場合もあります。

TypeA画像に特定の機能を与えたいときに問題が発生します。
TypeAイメージがImageから継承する場合、割り当てられたイメージと割り当てられていないイメージの機能を複製する必要があります。

これを行うためのより良い方法があると確信しています。大学時代にミックスインを使用したエレガントなソリューションをいくつか覚えていますが、ここでそれを使用する方法を見つけることができません。

私の現在のデザインは次のようになります。

class Image
{
public:
Image(int width, int height, int bpp);
virtual ~Image() {};
    // getters

    template <typename T>                                  
    T* ptr() { return reinterpret_cast<T*>(m_imageData); } // T depends on bpp

 protected:
    // metadata
    char* m_imageData;
};

class AllocImage : public Image
{
public:
    AllocImage(int width, int height, int bpp, DataType dataType) :
        Image(width, height, bpp, dataType)
    {
        m_imageData = new char[m_dataSize];
    }

    ~AllocImage()
    {
        delete m_imageData;
    }
};

class ImageHolder : public Image
{
public:
    ImageHolder(int width, int height, int bpp, DataType m_dataType);

    void setPtr(const void* ptr);
};

class AllocatedImageTypeA : public AllocImage
{
public:
    // Type A specific methods
};

class NonAllocatedImageTypeA : public ImageHolder
{
public:
    // duplicated Type A specific methods
};
4

3 に答える 3

1

すべての違いが画像の保持方法(割り当てられているかどうか)に制限されている場合は、ポリシーモデルを使用できます。

簡単な説明は、ポリシーオブジェクトを画像に渡すことです。ここで、ポリシーは、画像の割り当てを解除する必要があるかどうか、画像へのアクセス方法など、基本的に画像の方法から生じる違いに関連するすべてのものを記述します。データが保持されます(割り当てられたものと指摘されたもの)。その後、画像へのすべてのアクセスはポリシーを介して行われます。

たとえば、書く代わりに

delete image;

あなたは書くでしょう:

policy.del(image);

ポリシーの実際のタイプに応じて、どこpolicy.delに委任することもdelete、何もしないこともできます(つまり、イメージに必要なものと一致します)。

于 2012-05-01T12:04:56.180 に答える
0

なぜそんなに多くのタイプ?違いが割り当てのみにある場合は、複数のコンストラクターを作成するだけです。1つは事前に割り当てられたデータホルダーへのポインターを取得し、もう1つは内部で割り当てを実行しません。依存性注入を使用して、動作/機能のバリエーションを取得することもできます。

于 2012-05-01T12:15:18.263 に答える
0

私も同様のケースがありました。

何かを明確にしましょう。クラス階層は、イメージが割り当てられているかどうかに基づいていませんが、各クラスにはいくつかの機能があります。

画像を割り当てる非常に特殊なクラス、参照する別のクラス、および同様の機能を備えた同じ階層の別のクラスでそのクラスをワープするクラスが必要になる場合があります。

次の例は、同じ継承からの1つのクラスを別のクラスでラップするというアイデアを説明しています。これは、質問に当てはまるようです。

免責事項:無視してください、いくつかのマイナーなバグまたは関連性のない構文エラー:

// generic base class for my image library:
/* abstract */ class GenericImage
{
public:
   int width;
   int height;

public:
    /* constructor */ GenericImage() ;
    /* destructor */ ~GenericImage() ;

    /* constructor */ GenericImage(int newwidth, int newheight);
}; // class GenericImage

// in charge of allocating or deallocating an image
class AllocatedImage: GenericImage
{
public:
    /* constructor */ AllocatedImage() ;
    /* destructor */ ~AllocatedImage() ;

    /* constructor */ AllocatedImage(int newwidth, int newheight);
    /* constructor */ AllocatedImage(char* filename);
}; // class AllocatedImage

// access an image, but doesn't allocate or deallocate
class ContainedImage: GenericImage
{
public:
    /* constructor */ ContainedImage() ;
    /* destructor */ ~ContainedImage() ;

    /* constructor */ ContainedImage(int newwidth, int newheight);
}; // class AllocatedImage

// real working class, will allocate other objects,
// of same hierarchy
class WrapperImage: GenericImage
{
public:
   GenericImage* RealImage;

public:
    /* constructor */ GenericImage() ;
    /* destructor */ ~GenericImage() ;

   void AllocateImage(AllocatedImage* newimage);
   void HoldImage(ContainedImage* newimage);
}; // class AllocatedImage

提案:

  1. 特に、単一のクラスではなくクラス階層を設計する場合は、パラメーターなしのコンストラクターを使用することをお勧めします。

  2. 簡単な例を知っていますが、すべてのコードを本文ファイルに移動することをお勧めします。

乾杯。

于 2012-05-01T17:22:28.257 に答える