2

const フィールドメンバーを持つ基本 Image クラスがあります。

class Image {
protected:
    const int width;
    const int height;

public:
    virtual ~Image();
    const int getWidth() const;
    const int getHeight() const;

protected:
    Image(const int width, const int height);
};

これは、コンストラクターで、次のように初期化リストで幅と高さを初期化する必要があることを意味します。

Image::Image(const int width, const int height) :
        width(width), height(height) {
}

ここで、サブクラスにファイルパスを提供することで画像をロードできるように、これをサブクラス化するつもりです (したがって、呼び出しコードは画像のロードについて心配する必要はありません)。このクラスは次のようになります。

class GlImage: public Image {
private:
    const GLuint textureId;
    const int textureWidth;     // power of 2 width
    const int textureHeight;    // power of 2 height
    const double textureCoordinateX;
    const double textureCoordinateY;

public:
    GlImage(const string path); // is this constructor possible?
    virtual ~GlImage();
    const double getTextureCoordinateX() const;
    const double getTextureCoordinateY() const;

private:
    // what do we use for initialization functions?
};

ただし、ここでは、幅/高さを取得する前に画像をロードする必要があることがわかります。サブクラスには、初期化リストでも初期化する必要があるフィールドがあります。

これらすべてのフィールドを初期化できるように、サブクラスのコンストラクターをどのように設定できますか?

すべてのフィールドデータをキャプチャするサブクラスに別のオブジェクトを導入し、これを初期化リストの最初のオブジェクトとしてロードし、基本クラスが幅/高さを必要とするため、他のすべてのフィールドの値を再抽出することはできません。 (画像読み込みロジックが派生クラスにある場合は使用できません)。

const 修飾子を削除し、コンストラクターでフィールドを初期化する唯一の方法はありますか?

4

2 に答える 2

1

問題は、次元がわからないため、派生クラスの ctor 初期化子リストから基本クラスのコンストラクターを呼び出すことができないことですよね?

派生クラスに静的メソッドを作成してみませんか?

class GlImage: public Image {
    ....
    static GlImage LoadFromFile(const string& path)
    {
         // read image data and other info
         int w = ...
         int h = ...
         return GlImage(w, h, ....) 
         // of course, you would need a different ctor in derived class
         // it can even be private
    }
 }
于 2012-12-08T13:28:45.510 に答える
0

ロードを行う可変補助オブジェクトで委任コンストラクターを使用できます。

class GlImage: public Image {
    ...
    GlImage(const string& path) : GlImage(GlImageLoader(path))
    {
    }

private:
    struct GlImageLoader {
        int w;
        int h;
        GlImageLoader(const string& path) {
            //Read image data
            w = ...;
            h = ...;
        }
    };
    GlImage(GlImageLoader&& l) : Image(l.w, l.h), textureId(l.textureId), ...
    {
    }
};
于 2012-12-09T13:01:17.343 に答える