Risorsa condivisa di classe: soluzione corretta?
-
29-10-2019 - |
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;
}
}
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.