c++ - An alternative to PIMPL Idiom when you'd like the interface to have all the memory -


the purpose of pimpl idiom hide implementation, including methods, structures, , sizes of structures. 1 downside uses heap.

however, if didn't want hide size requirements of anything. wanted hide methods, formatting of structure , variable names. 1 way allocate array of bytes of perfect size, have implementation cast whatever structure , use that. manually find size of bytes allocate object? , casts time? not practical.

is there idiom or general way of handling case advantageous pimpl or opaque pointers.

a rather different approach rethink nature of objects represent. in traditional oop it's customary think of objects self-contained entities have own data , methods. of methods private class because they're required class's own housekeeping, , these kind of thing move 'impl' of pimpl class.

in recent project i've been favouring domain-driven design approach 1 of desirables separate data logic things it. data classes become little more structs, , complex logic hidden in pimpl can go in service object has no state of own.

consider (rather contrived) example of game loop:

class enemysoldier : public gameobject { public:     // implement basic gameobject interface     void        updatestate();     void        draw(surface&);  private:     std::unique_ptr<enemysoldierimp>  m_pimpl; }; 
class enemysolderimpl { public:       // 100 methods of complex ai logic       // don't want exposed clients  private:     statedata       m_statedata; }; 
void rungame() {     (auto gameobject : allgameobjects) {         gameobject->updatestate();     } } 

this restructured instead of gameobjects managing data and program logic, separate these 2 things out:

class enemysoldierdata { public:     // getters may allowed, other data      // modifiable service class. no program logic in class private:     friend class enemysoldieraiservice;     statedata       m_statedata; }; 
class enemysoldieraiservice { public:     enemysoldieraiservice() {}      void updatestate(game& game) {         (auto& enemysoldierdata : game.getallenemysoldierdata()) {             updatestateforsoldier(game, enemysoldierdata);         }     }      // 100 methods of ai logic here      // no state variables }; 

we don't have need pimpls or hacky tricks memory allocation. can use game programming technique of getting better cache performance , reduced memory fragmentation storing global state in several flat vectors rather needing array of pointers-to-base-classes, eg:

class game { public:         std::vector<enemysoldierdata> m_soldierdata;         std::vector<missiledata>     m_missiledata;         ... } 

i find general approach simplifies lot of program code:

  • there's less need pimpls
  • the program logic in 1 place
  • it's easier retain backwards compatibility or drop in alternate implementations choosing between v1 , v2 version of service class @ runtime
  • much less heap allocation

Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -