0

シングルトンパターンと一般的な「リソースマネージャー」を置き換える試みで、私は解決策を思いつきました。リソースを静的で保護します。そのリソースは、継承されたクラスのすべての子の間で共有されます。それは機能しますが、それが先に進むための良い方法であるかどうかはわかりませんでした。これが私がしていることを表現するための少しのコードです(ここのリソースはsf :: Textureです):

class Foo {
public:
    Foo() {
        if(m_texture == nullptr) {
            //Création et chargement de la texture
            m_texture = std::unique_ptr<sf::Texture>(new sf::Texture());
            m_texture->loadFromFile("...");
        }

    }

    void draw(sf::RenderWindow& window) = 0;

protected:
    static std::unique_ptr<sf::Texture> m_texture = nullptr;

};

class Bar : public Foo {
public:
    Bar()
        : m_sprite(*m_texture) {}

    void draw(sf::RenderWindow& window) {
        window.draw(m_sprite); 
    }

private:
    sf::Sprite m_sprite;
};

そうすれば、私のリソースはすべての子で共有され、一度だけ初期化されます。参照を通じてどこにでも持ち運べるシングルトンまたはリソースマネージャーを置き換えるのは良い解決策ですか。ありがとうございました!

4

2 に答える 2

1

基本的にあなたがやろうとしていることは正しいです、静的メンバーはすべての継承されたクラスの間で共有されます(つまりまったく同じです)、このようにあなたはあなたにたくさんのメモリを節約できる単一のインスタンスだけを必要としますがここにいくつかの問題があります...g++を使用していると仮定します。

クラス宣言内で非constメンバーを初期化することはできないので、これ。エラー:ISO C ++は、非const静的メンバーのクラス内初期化を禁止して
static std::unique_ptr<sf::Texture> m_texture = nullptr;
い ます。クラスのソースファイル内で、クラス外で初期化する必要があります。

std::unique_ptr<sf::Texture> Foo::m_texture = nullptr;

次に、メンバーフィールドに直接アクセスするために保存するのではなく、クラス関数内であっても、常にセッターとゲッターを使用します。これにより、コードがはるかに保守しやすくなります。そのため、getTextureと呼ばれる静的関数を持つことができます

static std::unique_ptr<sf::Texture> getTexture() {
    if(m_texture == nullptr) {
        //Création et chargement de la texture
        m_texture = std::unique_ptr<sf::Texture>(new sf::Texture());
        m_texture->loadFromFile("...");
    }
    return m_texture;
}

ifステートメントと関数呼び出しがオーバーヘッドを追加するのは事実ですが、これははるかに保守性と安全性が高く、本当に必要なときに最後の最後にテクスチャをロードします。

質問に戻りますが、シングルトンデザインパターンは非常にシンプルで、オブジェクトのインスタンスが1つしか作成されないため、ほとんどの場合メモリを節約するために使用されます:)リソースマネージャーはまったく異なる獣であり、読み込みに必要なすべてのアクションを一元化することを目標としています。リソースを管理し、2つを組み合わせて、リソースマネージャーの単一インスタンスを初期化し、静的メンバーフィールドを介してアクセスし、すべてのオブジェクトにリソースを要求させます。これは、何をしようとしているかに応じて、良い場合と悪い場合があります。成し遂げる。

ソフトウェアの設計は難しいです。私ができる最善のアドバイスはこれです。システムを設計するときは、「別の同様のコンポーネントを導入するために何行のコードを書く必要があるか」を自問してください。目標は、これを可能な限り最小限に抑えること、つまり再利用することです。可能な限り、あなたがすでに作成したもの。

最高のプログラマーは最も怠惰です:)そして私はコピー/貼り付けを意味するのではなく、それは禁止されるべきです。

于 2012-06-10T02:55:56.327 に答える
0

デザインは疑わしいようです。より広く使用されているシングルトンパターン(関数ローカル静的インスタンスを使用)よりもこれを使用する利点はありません。おそらく、定義の時点で('s ctor内ではなく)m_textureデフォルトでオブジェクトを初期化するのが最善です。TextureFoo

static std::unique_ptr<sf::Texture> m_texture( new sf::Texture() );

データメンバーは、派生クラスに最適です。基本クラスは通常、インターフェースを定義するためのものです。

Fooリソースマネージャークラス( )を分離し、継承する代わりに、適切なメンバー関数を呼び出してオブジェクトにアクセスすることをお勧めしTextureます。

于 2012-06-10T01:41:31.043 に答える