c++ - Casting from abstract base class pointer to derived class -


i'm trying create state manager game, , have 4 classes:

gamestate:

  // foward declaration avoid circular-referency   class statemanager;    class gamestate   {     public:       virtual ~gamestate() { }           virtual void update(statemanager* gamemanager) = 0;       virtual void draw(statemanager* gamemanager) = 0;     protected:       gamestate() { }   }; 

statemanager:

  class statemanager   {     public:       statemanager();       virtual ~statemanager();        void addstate(gamestate* gamestate);       void update(statemanager* statemanager);       void draw(statemanager* statemanager);      protected:       // store states in unique_ptr avoid memory leak       std::vector<std::unique_ptr<gamestate> > states_;   }; 

game:

class game : public statemanager { public:   void compute()   {     // call methos of statemanager     update(this);     draw(this);   } } 

and mainmenu:

class mainmenu : public gamestate {   public:     // override pure virtual methos of gamestate     void update(statemanager* statemanager)     {       // problem here.       // need handle instance of game in class,        // pointer 1 statemanager     }     void draw(statemanager* statemanager) {} } 

when initialize game so: game.addstate(new mainmenu()).

the way can access class game in mainmenu casting pointer?

// mainmenu class void update(statemanager* statemanager) {     game* game = (game*) statemanager;     game.input.getkey(any_key);     //... } 

is right? tells me i'm doing wrong.

the answer of immibis perfect addressing technical casting issue.

nevertheless there's weird in design. i'd provide alternative answer, addressing design issues.

first statemanager not gamestate. there no need have same signature update() , draw(). ever foresee have 1 of these statemanager functions called statemanager in argument ? game, think makes no sense. i'd recommend refactor class (and adapt game accordingly):

class statemanager { public:     ...     void update();  // know "this".       void draw(); protected:     ... }; 

next, seems statemanager owns gamestate (the protected vector using unique_ptr<>,and casting question suggest it). design interesting well:

class gamestate { public:     virtual ~gamestate() { }         virtual void update() = 0;     virtual void draw() = 0; protected:     gamestate(statemanager* gamemanager) { }  // gamestates created statemanager     statemanager* gm;   // manager can used gamestate functions need }; 

following logic, mainmenu refactored as:

class mainmenu : public gamestate { public:     mainmenu (game* g) : game(g), gamestate(g) {}     void update()     {         // no longer needed:  game* game = (game*) statemanager;         game->input.getkey(any_key);         // no more problems here:  refer right object without overhead     }     void draw() {} protected:       game *game;   // owning game.   };   

the advantages of alternative design are:

  • the code lighter, , less error prone, don't worry member function's argument.
  • statemanager pointer used statemanager abstraction.
  • concerete implementations of gamestate, rely on game, can use directly, should use game specific abstractions.

the main inconveniences are:

  • gamestate must created 1 specifc statemanager.
  • the robustness of design comes @ cost of redundant pointer in gamestate implementations such mainmenu . if have millions of them, become memory issue.

Popular posts from this blog