Mi chiedo quale sia il modo migliore per andare sull'inizializzazione e la memorizzazione degli oggetti per quanto riguarda gli oggetti che devono avere un ambito relativamente lungo/una lunga durata. Supponiamo di avere una classe GameEngine
che deve essere inizializzata e contenere un riferimento a un Window
per il rendering. Il riferimento è necessario per tutta la vita del programma e la finestra deve conoscere le sue dimensioni, almeno.Come gestire al meglio l'inizializzazione dell'oggetto C++: costruttori o puntatori vuoti?
In Java, lo farei in questo modo:
// Declaration:
Window window;
// Initialization:
window = new Window(width, height);
ho capito che in C++, il primo sarebbe già chiamare il costruttore di default della classe Window, quindi essere dichiarazione e inizializzazione . Avere un window = Window(width, height);
sarebbe quindi assegnazione, buttando via l'oggetto già esistente.
La prima soluzione che ho trovato è stato quello di usare un puntatore:
// GameEngine.hpp
class GameEngine {
Window *window;
};
// Somewhere in GameEngine.cpp:
window = new Window(width, height);
Ma poi di nuovo, ho sempre letto uno dovrebbe favorire gli oggetti semplici oltre puntatori quando possibile e in effetti, mi sono fatto in un pasticcio di segnalatori in poco tempo, quindi sto cercando un altro modo.
Un'altra soluzione sembra per progettare gli oggetti ad avere un costruttore senza parametri e impostare l'oggetto in seguito:
// GameEngine.hpp
class GameEngine {
Window window;
};
// Somewhere in GameEngine.cpp
window.setWidth(width);
window.setHeight(height);
questo funziona, ma ha un grave inconveniente: l'oggetto (almeno in questo caso) potrebbe essere in uno stato incoerente, poiché provare a visualizzare la finestra senza impostare larghezza/altezza causerebbe un errore o un arresto anomalo. Funziona per alcuni oggetti, ma per la maggior parte non lo fa.
Un modo per evitare questo sarebbe avere valori predefiniti. Ad esempio, il costruttore della classe Window potrebbe assomigliare a questo:
Window::Window(int width = 800, int height = 600) {}
O anche come quella:
Window::Window() : width(DEFAULT_WIDTH), height(DEFAULT_HEIGHT) {}
Ma in molti casi, i valori di default sarà difficile da determinare. Inoltre, da dove dovrebbero venire? La classe Window dovrebbe definire DEFAULT_WIDTH
e DEFAULT_HEIGHT
? O dovrei farlo anche io?
// GameEngine.hpp
class GameEngine {
static const int DEFAULT_WIDTH = 800;
static const int DEFAULT_HEIGHT = 600;
Window window(800,600);
};
Ma che sembra male, come ho letto che non si deve fare alcuna inizializzazione nell'intestazione, solo la dichiarazione, in modo che i valori di DEFAULT_WIDTH
e DEFAULT_HEIGHT
non dovrebbe in realtà essere conosciuto a questo punto (e solo essere inizializzato in .cpp, corretto?).
Mi manca un'opzione? Oppure è comune in C++ assumere che il programmatore dovrebbe sapere cosa sta facendo e occuparsi di ottenere i suoi oggetti in uno stato consistente prima di usarli? Quando utilizzare quale approccio?
@close voto - questo non mi sembra una domanda basata sull'opinione pubblica. Anche se un po 'mal formulata (probabilmente a causa della mancanza di comprensione) la domanda riguarda davvero i tecnicismi del linguaggio C++. – Cubic
I * think * si sta chiedendo come eseguire l'inizializzazione a due fasi –
Mi sento come se mi mancasse qualcosa; c'è un motivo per cui non puoi creare l'oggetto Window e inizializzarlo allo stesso tempo? Hai bisogno che la dichiarazione e l'inizializzazione siano in posti diversi? Perché se non lo fai, includi semplicemente l'inizializzazione nella dichiarazione di dichiarazione e non ci sono problemi. – goldfire