Domanda

Questi non sono compiti a casa, solo una domanda sul mio codice (sto imparando il C++).

Ho più istanze della classe Renderer che utilizzano tutti la stessa risorsa, un BMP caricato da SDL.È questo un modo corretto di gestire una risorsa condivisa per una classe?In caso contrario, qual è quello buono?Se sì, ce ne sono di migliori?

renderer.hpp

class Renderer {
    public:
        Renderer(SDL_Surface *target_surface, int w, int h);
        Renderer(const Renderer& renderer);
        ~Renderer();
        // ...
    private:
        int w, h;
        SDL_Surface *target;

        static SDL_Surface *blocks;
        static int numinstances;
};

renderer.cpp

const char BLOCKS_FILE[] = "blocks.bmp";
SDL_Surface *Renderer::blocks = 0;
int Renderer::numinstances = 0;

Renderer::Renderer(SDL_Surface *target, int w, int h) {
    numinstances++;

    if (blocks == 0) {
        // temporary storage for file
        SDL_Surface *loadedimg = SDL_LoadBMP(BLOCKS_FILE);
        if (loadedimg != NULL) {
            blocks = SDL_DisplayFormat(loadedimg);
            SDL_FreeSurface(loadedimg);
        }

    }

    this->target = target;
    this->w = w;
    this->h = h;
}

Renderer::Renderer(const Renderer& renderer) {
    numinstances++;

    w = renderer.w;
    h = renderer.h;
    target = renderer.target;

}

Renderer::~Renderer() {
    numinstances--;

    if (numinstances == 0) {
        SDL_FreeSurface(blocks);
        blocks = 0;
    }
}
È stato utile?

Soluzione

È questo un modo corretto di gestire una risorsa condivisa per una classe?

Sì, in senso stretto lo è UN modo corretto.Ma è uno di quelli da cui dovresti allontanarti il ​​più velocemente possibile.No, non camminare, corri.E non guardare indietro.

In caso contrario, qual è quello buono?

Preferisci tutto ciò che gli somiglia std::shared_ptr<> O boost::shared_ptr<>.

Se sì, ce ne sono di migliori?

Invece di avere un puntatore di superficie statico e un contatore di riferimento statico all'interno della classe, mantienine semplicemente uno shared_ptr per la superficie lì, creala una volta all'esterno della classe e quindi passarlo al costruttore del renderer.Alcuni vantaggi di farlo:

(Modifica in grassetto:)

  • Non hai bisogno di pensare su chi è l'ultimo proprietario e quindi responsabile dell'eliminazione delle risorse, da allora shared_ptr lo fa per te.
  • Sicurezza del filo
  • Meno codice spesso significa meno bug.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top