-----------------------------------------------------------------------------
Compoiste 객체를 Visitor가 순회할때 자식 객체들은 Accept를 재귀호출하고 자신은 Visit를
수행하는 방법으로 순회 한다.
--------------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>

#include <list>
#include <string>
#include <algorithm>
#include <iostream>
#include <deque>


/////////////////////////////////////////////////////////////////////////////
//
// Base Patterns
//
//
/////////////////////////////////////////////////////////////////////////////

//// ------------------------------------------------------------------------
////  Visitor Pattern
//// ------------------------------------------------------------------------
class Visitable;

class Visitor
{
protected:
 Visitor() {}
public:
 virtual void Visit (Visitable *) {}
};

class Visitable
{
protected:
 Visitable() {}
public:
 virtual void Accept (Visitor &v)
 {
  v.Visit (this);
 }
};

class VisitableObjectAcceptor
{
protected:
 Visitor &Visitor_;

public:
 explicit VisitableObjectAcceptor (Visitor &v) : Visitor_(v)
 {
 }

public:
 void operator () (Visitable* o)
 {
  if (o)
  {
   o->Accept (Visitor_);
  }
 }
};

//// ------------------------------------------------------------------------
////  Composite Pattern
//// ------------------------------------------------------------------------
class Composite;

class Component : public Visitable
{
public:
 virtual Composite* GetComposite (void)
 {
  return 0;
 }

 virtual void Add   (Component* c) {};
 virtual void Remove(Component* c) {};
};

class Composite : public Component
{
protected:
 Composite () {}

public:
 virtual Composite* GetComposite (void)
 {
  return this;
 }

public:
 virtual void Add (Component* c)
 {
  components_.push_back (c);
 };

 virtual void Remove(Component* c)
 {
  components_.remove (c);
 };

 virtual void Accept (Visitor &v)
 {
  v.Visit (this);
  std::for_each(components_.begin(), components_.end(), VisitableObjectAcceptor(v));

 }

protected:
 std::list <Component*> components_;
};

class Leaf : public Component
{
};


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
//
/////////////////////////////////////////////////////////////////////////////

//// ------------------------------------------------------------------------
////  Composite
//// ------------------------------------------------------------------------
class Directory : public Composite
{
public:
 Directory (const std::string name) : name_ (name)
 {
 }

public:
 virtual std::string GetName      (void) const { return name_;              }
 virtual size_t      GetFileCount (void) const { return components_.size(); }

protected:
 std::string name_;
};

class File : public Leaf
{
public:
 File (const std::string name, int size=0) : name_ (name), size_(size)
 {
 }

public:
 virtual int         GetSize (void) const { return size_; }
 virtual std::string GetName (void) const { return name_; }

protected:
 std::string name_;
 int         size_;
};

class Mp3File : public File
{
public:
 Mp3File (const std::string filename) : File (filename, 1000) {}
};

class TxtFile : public File
{
public:
 TxtFile (const std::string filename) : File (filename, 10) {}
};

//// ------------------------------------------------------------------------
////  Vistor
//// ------------------------------------------------------------------------
class Enumerator: public Visitor
{
public:
 Enumerator ()
 {
 }

public:
 virtual void Visit (Visitable *o)
 {
  File      *file=dynamic_cast<File*>      (o);
  Directory *dir =dynamic_cast<Directory*> (o);

  if (file) std::cout << "\"" << file->GetName() << "\"" << std::endl;
  if (dir ) std::cout << "["  << dir ->GetName() << "]"  << std::endl;
 }
};

class CalcTotalSize : public Visitor
{
public:
 CalcTotalSize () : m_TotalSize(0)
 {
 }

public:
 virtual void Visit (Visitable *o)
 {
  File *file=dynamic_cast<File*> (o);

  if (file)
  {
   m_TotalSize+=file->GetSize();
  }
 }

public:
 int GetTotalSize (void) { return m_TotalSize; }

private:
 int m_TotalSize;
};


/////////////////////////////////////////////////////////////////////////////
//
// Start up
//
//
/////////////////////////////////////////////////////////////////////////////

int _tmain (int argc, _TCHAR* argv[])
{
 Directory dir_root   ("RootDirectory");
 Directory dir_sub1   ("SubDirectory1");
 Directory dir_sub2   ("SubDirectory2");
 Mp3File   file_mp3_1 ("a.mp3");
 Mp3File   file_mp3_2 ("b.mp3");
 TxtFile   file_txt_1 ("a.txt");
 TxtFile   file_txt_2 ("b.txt");


 dir_sub1.Add (&file_mp3_1);
 dir_sub1.Add (&file_mp3_2);
 dir_sub2.Add (&file_mp3_1);
 dir_sub2.Add (&file_txt_1);

 dir_root.Add (&dir_sub1);
 dir_root.Add (&dir_sub2);

 dir_root.Add (&file_txt_1);
 dir_root.Add (&file_txt_2);


 CalcTotalSize calc_size;

 dir_root.Accept (calc_size);
 std::cout << "# CalcTotalSize::GetTotalSize()=" << calc_size.GetTotalSize() << std::endl;


 std::cout << std::endl;


 std::cout << "# Enumerator" << std::endl;
 Enumerator show_enum;

 dir_root.Accept (show_enum);

 return 0;
}

--------------------------------------------------------------------------------
# CalcTotalSize::GetTotalSize()=3030

# Enumerator
[RootDirectory]
[SubDirectory1]
"a.mp3"
"b.mp3"
[SubDirectory2]
"a.mp3"
"a.txt"
"a.txt"
"b.txt"

Posted by 셈말짓기 :

#include <windows.h>
#include <tchar.h>

#include <map>
#include <string>
#include <iostream>

using namespace std;

class GameObject
{
public:
 virtual ~GameObject() {};
};

class SpaceShip: public GameObject
{
};

class SpaceStation: public GameObject
{
};


class Asteriod: public GameObject
{
};

class CollisionMap
{
public:
 typedef void (*HitFunctionPtr) (GameObject&, GameObject&);
public:
 typedef map<pair<string, string>, HitFunctionPtr> HitMap;

public:
 void AddEntry (const string& type1, const string& type2, HitFunctionPtr collisionFunction, bool symmetric = true);

 void RemoveEntry (const string& type1, const string& type2);

 HitFunctionPtr Lookup(const string& type1, const string& type2);

 static CollisionMap& TheCollisionMap ();

public:
 pair<string, string> MakeStringPair(const char *s1, const char *s2);

 CollisionMap () {};
 CollisionMap (const CollisionMap &) {}

public:
 HitMap map_; 

};

class RegisterCollisionFunction
{
public:
 RegisterCollisionFunction (const string& type1, const string& type2, CollisionMap::HitFunctionPtr collisionFunction, bool symetric = true)
 {
  CollisionMap::TheCollisionMap().AddEntry(type1, type2, collisionFunction, symetric);
 }
};

CollisionMap& CollisionMap::TheCollisionMap ()
{
 static CollisionMap map;

 return map;
}

inline pair<string, string> CollisionMap::MakeStringPair(const char *s1, const char *s2)
{
 return pair<string, string>(s1, s2);
}

inline void CollisionMap::AddEntry (const string& type1, const string& type2, HitFunctionPtr collisionFunction, bool symmetric)
{
 string temp1;
 string temp2;

 temp1 = "class " + type1;
 temp2 = "class " + type2;

 map_ [MakeStringPair (temp1.c_str(), temp2.c_str())] = collisionFunction;
}

inline  void CollisionMap::RemoveEntry (const string& type1, const string& type2)
{
 string temp1;
 string temp2;

 temp1 = "class " + type1;
 temp2 = "class " + type2;

 map_.erase(MakeStringPair (temp1.c_str(), temp2.c_str()));
}

inline CollisionMap::HitFunctionPtr CollisionMap::Lookup(const string& type1, const string& type2)
{
 HitMap::iterator mapEntry = map_.find ( MakeStringPair(type1.c_str(), type2.c_str()) );

 if (mapEntry == map_.end () ) return 0;

 return (*mapEntry).second;
}

void ShipShip(GameObject& shipObject1, GameObject& shipObject2)
{
 SpaceShip& ship1 = dynamic_cast<SpaceShip&> (shipObject1);
 SpaceShip& ship2 = dynamic_cast<SpaceShip&> (shipObject2);

 cout << "The space ship is colliding with a space ship" << endl;
}

void ShipAsteriod(GameObject& shipObject, GameObject& asteriodObject)
{
 SpaceShip& ship = dynamic_cast<SpaceShip&> (shipObject);
 Asteriod& asteriod = dynamic_cast<Asteriod&> (asteriodObject);

 cout << "The space ship is colliding with a asteriod" << endl;
}

void ShipSation(GameObject& shipObject, GameObject& stationObject)
{
 SpaceShip& ship = dynamic_cast<SpaceShip&> (shipObject);
 SpaceStation& station = dynamic_cast<SpaceStation&> (stationObject);

 cout << "The space ship is colliding with a space station" << endl;
}


void AsteriodAsteriod(GameObject& asteriodObject1, GameObject& asteriodObject2)
{
 Asteriod& asteriod1 = dynamic_cast<Asteriod&> (asteriodObject1);
 Asteriod& asteriod2 = dynamic_cast<Asteriod&> (asteriodObject2);

 cout << "The asteriod is colliding with a asteriod" << endl;
}

void AsteriodShip(GameObject& asteriodObject, GameObject& shipObject)
{
 Asteriod& asteriod = dynamic_cast<Asteriod&> (asteriodObject);
 SpaceShip& ship = dynamic_cast<SpaceShip&> (shipObject);

 cout << "The asteriod is colliding with a space ship" << endl;
}

void AsteriodSation(GameObject& asteriodObject, GameObject& stationObject)
{
 Asteriod& asteriod = dynamic_cast<Asteriod&> (asteriodObject);
 SpaceStation& station = dynamic_cast<SpaceStation&> (stationObject);

 cout << "The asteriod is colliding with a space staion" << endl;
}

void StationStation(GameObject& stationObject1, GameObject& stationObject2)
{
 SpaceStation& station1 = dynamic_cast<SpaceStation&> (stationObject1);
 SpaceStation& station2 = dynamic_cast<SpaceStation&> (stationObject2);

 cout << "The space station is colliding with a space station" << endl;
}

void StationShip(GameObject& stationObject, GameObject& shipObject)
{
 SpaceStation& station = dynamic_cast<SpaceStation&> (stationObject);
 SpaceShip& ship = dynamic_cast<SpaceShip&> (shipObject);

 cout << "The space staion is colliding with a space ship" << endl;
}

void StationAsteriod(GameObject& stationObject, GameObject& asteriodObject)
{
 SpaceStation& station = dynamic_cast<SpaceStation&> (stationObject);
 Asteriod& asteriod = dynamic_cast<Asteriod&> (asteriodObject);

 cout << "The space station is colliding with a asteriod" << endl;
}

void AsteriodStation(GameObject& aa, GameObject& bb)
{
 Asteriod& a = dynamic_cast<Asteriod&> (aa);
 SpaceStation& b = dynamic_cast<SpaceStation&> (bb);

 cout << "The space station is colliding with a asteriod" << endl;
}

void ProcessCollision(GameObject& object1, GameObject& object2)
{
 CollisionMap::HitFunctionPtr phf = CollisionMap::TheCollisionMap().Lookup(typeid(object1).name(), typeid(object2).name());

 if (phf)
  phf(object1, object2);
 else
 {
  cout << "Unknown object type" << endl;
 }
}

RegisterCollisionFunction cf1 ("SpaceShip", "Asteriod", &ShipAsteriod);
RegisterCollisionFunction cf2 ("SpaceShip", "SpaceStation", &ShipSation);
RegisterCollisionFunction cf3 ("SpaceShip", "SpaceShip", &ShipShip);

RegisterCollisionFunction cf4 ("Asteriod", "Asteriod", &AsteriodAsteriod);
RegisterCollisionFunction cf5 ("Asteriod", "SpaceShip", &AsteriodShip);
RegisterCollisionFunction cf6 ("Asteriod", "SpaceStation", &AsteriodSation);

RegisterCollisionFunction cf7 ("SpaceStation", "SpaceStation", &StationStation);
RegisterCollisionFunction cf8 ("SpaceStation", "SpaceShip", &StationShip);
RegisterCollisionFunction cf9 ("SpaceStation", "Asteriod", &StationAsteriod);

int _tmain(int argc, _TCHAR* argv[])
{
 GameObject* ship = new SpaceShip;
 GameObject* station = new SpaceStation;
 GameObject* asteriod = new Asteriod;


 ProcessCollision(*station,*ship);
 ProcessCollision(*ship, *ship);
 ProcessCollision(*ship, *asteriod);

 delete ship;
 delete station;
 delete asteriod;

 return 0;
}
----------------------------------------------------------------------
The space staion is colliding with a space ship
The space ship is colliding with a space ship
The space ship is colliding with a asteriod

Posted by 셈말짓기 :

구조패턴-Composite

2008. 8. 5. 00:15 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Composite]
의도:
부분-전체 계층을 나타내기 위핸 복합 객체를 트리 구조로 만든다.
Composite 패턴은 클라이언트가 개별적 객체와 복합 객체 모두를 동일하게 다루도록
한다.

설명:
순환구조일때 즉, Compoiste구조에서 A와 B가 있을때 A는 B를 Child 객체로 소유하고, 또한
B가 A를 Child로 소유하고 있을 경우 A와 B가 Handle로 구현되어있는 경우 서로 Reference-
Counting으로 관계가 있기 때문에 Memory Leak이 생길 수 있다.  이를 해결하기 위해서는
Gabege-collector를 구현해야 하는데, 그냥 Handle로 안하는 것이 정신 건강에 이롭다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Composite
//
/////////////////////////////////////////////////////////////////////////////


#include <windows.h>
#include <tchar.h>

#include <list>
#include <string>
#include <algorithm>
#include <iostream>
#include <deque>


/////////////////////////////////////////////////////////////////////////////
//
// Composite
//
/////////////////////////////////////////////////////////////////////////////
class Composite;

class Component
{
public:
 explicit Component (const std::string name) : name_ (name)
 {
 }

public:
 virtual Composite* GetComposite (void)
 {
  return 0;
 }

 virtual void Add   (Component* c) {};
 virtual void Remove(Component* c) {};

public:
 virtual std::string GetName (void) const { return name_; }

protected:
 std::string name_;
};

class Composite : public Component
{
public:
 explicit Composite (const std::string name) : Component(name) {}

public:
 virtual Composite* GetComposite (void)
 {
  return this;
 }

public:
 virtual void Add (Component* c)
 {
  components_.push_back (c);
 };

 virtual void Remove(Component* c)
 {
  components_.remove (c);
 };

 virtual std::list<Component*>* GetChilds (void)
 {
  return &components_;
 }

protected:
 std::list <Component*> components_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
void ShowComposite (Composite* composite, int indent)
{
 int i;

 for (i=0; i<indent; i++)
  std::cout << "   ";

 std::cout << "[" << composite->GetName() << "]" << std::endl;

 std::list <Component*>::iterator child;

 indent++;
 for (child=composite->GetChilds()->begin();
      child!=composite->GetChilds()->end();
      child++)
 {
  if (0==(*child)->GetComposite())
  {
   for (i=0; i<indent; i++)
    std::cout << "   ";
   std::cout << (*child)->GetName() << std::endl;
  }
  else
  {
   ShowComposite ((*child)->GetComposite(), indent);
  }
 }
 indent--;
}

int _tmain (int argc, _TCHAR* argv[])
{
 Composite Root ("Root");
 Composite Sub1 ("Sub1");
 Composite Sub2 ("Sub2");
 Component Item1("Item1");
 Component Item2("Item2");
 Component Item3("Item3");
 Component Item4("Item4");
 Component Item5("Item5");

 Root.Add (&Sub1);
 Root.Add (&Sub2);
 Root.Add (&Item1);

 Sub1.Add (&Item2);
 Sub1.Add (&Item3);

 Sub2.Add (&Item4);
 Sub2.Add (&Item5);

 ShowComposite (&Root, 0);

 return 0;
}
-----------------------------------------------------------------------------
[Root]
   [Sub1]
      Item2
      Item3
   [Sub2]
      Item4
      Item5
   Item1

Posted by 셈말짓기 :

행위패턴-Visitor

2008. 8. 4. 22:52 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Visitor]
의도:
객체 구조의 요소들에 수행할 오퍼레이션을 표한한 패턴이다. Visitor 패턴은
오퍼레이션이 처리할 요소의 클래스를 변경하지 않고도 새로운 오퍼레이션을
정의 할 수 있게한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Visitor
//
/////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <list>

class ElementA;
class ElementB;
class CompoisteElement;

/////////////////////////////////////////////////////////////////////////////
//
// Visitor base
//
/////////////////////////////////////////////////////////////////////////////
class Visitor
{
protected:
 Visitor();
public:
 virtual ~Visitor();

public:
 virtual void VisitElementA (ElementA *);
 virtual void VisitElementB (ElementB *);
 virtual void VisitCompoistElement(CompoisteElement *);
};

Visitor::Visitor() {}
Visitor::~Visitor() {}

void Visitor::VisitElementA (ElementA *)
{
 std::cout << "Visitor::VisitElementA (ElementA *)" << std::endl;
}

void Visitor::VisitElementB (ElementB *)
{
 std::cout << "Visitor::VisitElementB (ElementA *)" << std::endl;
}

void Visitor::VisitCompoistElement(CompoisteElement *)
{
 std::cout << "Visitor::VisitCompoistElement (ElementA *)" << std::endl;
}


/////////////////////////////////////////////////////////////////////////////
//
// Element base
//
/////////////////////////////////////////////////////////////////////////////
class Element
{
protected:
 Element ();
public:
 virtual ~Element ();

public:
 virtual void Accept (Visitor &) = 0;
};

Element::Element () {};
Element::~Element () {};


/////////////////////////////////////////////////////////////////////////////
//
// Elements
//
/////////////////////////////////////////////////////////////////////////////
class ElementA : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementA (this);
 }
};

class ElementB : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementB (this);
 }
};

class CompoisteElement : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  std::list<Element*>::iterator i;

  for (i=childs_.begin(); i!=childs_.end(); i++)
  {
   (*i)->Accept (v);
  }

  v.VisitCompoistElement (this);
 }
public:
 std::list<Element*> childs_;
};

/////////////////////////////////////////////////////////////////////////////
//
// Visitors
//
/////////////////////////////////////////////////////////////////////////////
class VisitorA : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorA::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorA::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorA::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};

class VisitorB : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorB::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorB::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorB::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ElementA         element_a;
 ElementB         element_b;
 CompoisteElement c_element;

 c_element.childs_.push_back (&element_a);
 c_element.childs_.push_back (&element_b);

 VisitorA visitor_a;
 VisitorB visitor_b;

 element_a.Accept (visitor_a);
 element_b.Accept (visitor_a);
 c_element.Accept (visitor_a);

 std::cout << std::endl;

 element_a.Accept (visitor_b);
 element_b.Accept (visitor_b);
 c_element.Accept (visitor_b);

 std::cout << std::endl;
 std::cout << std::endl;
 std::cout << std::endl;


 Element *e;

 std::cout << "by element_a" << std::endl;
 e = &element_a;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by element_b" << std::endl;
 e = &element_b;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by c_element" << std::endl;
 e = &c_element;
 e->Accept (visitor_a);
 e->Accept (visitor_b);

 return 0;
}
-----------------------------------------------------------------------------
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)

VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)


by element_a
VisitorA::VisitElementA (ElementA *)
VisitorB::VisitElementA (ElementA *)

by element_b
VisitorA::VisitElementB (ElementB *)
VisitorB::VisitElementB (ElementB *)

by c_element
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)

Posted by 셈말짓기 :

#include <windows.h>
#include <tchar.h>

#include <map>
#include <string>
#include <iostream>

using namespace std;

class GameObject
{
public:
 virtual void Collide(GameObject& otherObject) = 0;
 virtual ~GameObject() {};
};

class SpaceShip: public GameObject
{
private:
 typedef void (SpaceShip::*HitFunctionPtr) (GameObject&);
 typedef map< std::string, HitFunctionPtr > HitMap;

public:
 virtual void Collide (GameObject& otherObject);
 virtual void HitSpaceShip (GameObject& spaceShip);
 virtual void HitSpaceStation (GameObject& spaceStation);
 virtual void HitAsteriod (GameObject& asteroid);

private:
 static HitFunctionPtr Lookup (const GameObject& whatWeHit);
 static HitMap* InitializeCollisionMap ();
};

class SpaceStation: public GameObject
{
private:
 typedef void (SpaceStation::*HitFunctionPtr) (GameObject&);
 typedef map<std::string, HitFunctionPtr> HitMap;
public:
 virtual void Collide (GameObject& otherObject);
 virtual void HitSpaceShip (GameObject& spaceShip);
 virtual void HitSpaceStation (GameObject& spaceStation);
 virtual void HitAsteriod (GameObject& asteroid);

private:
 static HitFunctionPtr Lookup (const GameObject& whatWeHit);
 static HitMap* InitializeCollisionMap ();
};

class Asteroid: public GameObject
{
private:
 typedef void (Asteroid::*HitFunctionPtr) (GameObject&);
 typedef map<std::string, HitFunctionPtr> HitMap;
public:
 virtual void Collide (GameObject& otherObject);
 virtual void HitSpaceShip (GameObject& spaceShip);
 virtual void HitSpaceStation (GameObject& spaceStation);
 virtual void HitAsteriod (GameObject& asteroid);

private:
 static HitFunctionPtr Lookup (const GameObject& whatWeHit);
 static HitMap* InitializeCollisionMap ();
};

SpaceShip::HitMap* SpaceShip::InitializeCollisionMap ()
{
 HitMap* phm = new HitMap;

 (*phm) ["class SpaceShip"]    = &HitSpaceShip;
 (*phm) ["class SpaceStation"] = &HitSpaceStation;
 (*phm) ["class Asteroid"]     = &HitAsteriod;

 return phm;
}

SpaceShip::HitFunctionPtr
SpaceShip::Lookup (const GameObject& whatWeHit)
{
 static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );

 HitMap::iterator mapEntry = collisionMap->find ( string (typeid (whatWeHit).name ()) );

 if (mapEntry == collisionMap->end () ) return 0;

 return (*mapEntry).second;
}

void SpaceShip::Collide (GameObject& otherObject)
{
 HitFunctionPtr hfp = Lookup (otherObject);

 if (hfp)
 {
  (this->*hfp)(otherObject);
 }
 else
 {
  cout << "Unknown object type" << endl;
 }
}

void SpaceShip::HitSpaceShip (GameObject& spaceShip)
{
 SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);

 cout << "The space ship is colliding with a space ship";
 cout << endl;
}

void SpaceShip::HitSpaceStation (GameObject& spaceStation)
{
 SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);

 cout << "The space ship is colliding with a space station";
 cout << endl;
}

void SpaceShip::HitAsteriod (GameObject& obj)
{
 Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);

 cout << "The space ship is colliding with a asteroid";
 cout << endl;
}

SpaceStation::HitMap* SpaceStation::InitializeCollisionMap ()
{
 HitMap* phm = new HitMap;

 (*phm) ["class SpaceShip"   ] = &HitSpaceShip;
 (*phm) ["class SpaceStation"] = &HitSpaceStation;
 (*phm) ["class Asteroid"    ] = &HitAsteriod;

 return phm;
}

SpaceStation::HitFunctionPtr
SpaceStation::Lookup (const GameObject& whatWeHit)
{
 static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );

 HitMap::iterator mapEntry = collisionMap->find ( string(typeid (whatWeHit).name ()) );

 if (mapEntry == collisionMap->end () ) return 0;

 return (*mapEntry).second;
}

void SpaceStation::Collide (GameObject& otherObject)
{
 HitFunctionPtr hfp = Lookup (otherObject);

 if (hfp)
 {
  (this->*hfp)(otherObject);
 }
 else
 {
  cout << "Unknown object type" << endl;
 }
}

void SpaceStation::HitSpaceShip (GameObject& spaceShip)
{
 SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);

 cout << "The space ship is colliding with a space ship";
 cout << endl;
}

void SpaceStation::HitSpaceStation (GameObject& spaceStation)
{
 SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);

 cout << "The space ship is colliding with a space station";
 cout << endl;
}

void SpaceStation::HitAsteriod (GameObject& obj)
{
 Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);

 cout << "The space ship is colliding with a asteroid";
 cout << endl;
}

Asteroid::HitMap* Asteroid::InitializeCollisionMap ()
{
 HitMap* phm = new HitMap;

 (*phm) ["class SpaceShip"   ] = &HitSpaceShip;
 (*phm) ["class SpaceStation"] = &HitSpaceStation;
 (*phm) ["class Asteroid"    ] = &HitAsteriod;

 return phm;
}

Asteroid::HitFunctionPtr
Asteroid::Lookup (const GameObject& whatWeHit)
{
 static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );

 HitMap::iterator mapEntry = collisionMap->find ( string(typeid (whatWeHit).name ()) );

 if (mapEntry == collisionMap->end () ) return 0;

 return (*mapEntry).second;
}

void Asteroid::Collide (GameObject& otherObject)
{
 HitFunctionPtr hfp = Lookup (otherObject);

 if (hfp)
 {
  (this->*hfp)(otherObject);
 }
 else
 {
  cout << "Unknown object type" << endl;
 }
}

void Asteroid::HitSpaceShip (GameObject& spaceShip)
{
 SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);

 cout << "The space ship is colliding with a space ship";
 cout << endl;
}

void Asteroid::HitSpaceStation (GameObject& spaceStation)
{
 SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);

 cout << "The space ship is colliding with a space station";
 cout << endl;
}

void Asteroid::HitAsteriod (GameObject& obj)
{
 Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);

 cout << "The space ship is colliding with a asteroid";
 cout << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
 SpaceShip    ship;
 SpaceStation station;
 Asteroid  asteroid;

 ship.Collide(station);
 ship.Collide(asteroid);
 ship.Collide(ship);
 ship.Collide(asteroid);

 return 0;
}
--------------------------------------------------------------------------
The space ship is colliding with a space station
The space ship is colliding with a asteroid
The space ship is colliding with a space ship
The space ship is colliding with a asteroid

Posted by 셈말짓기 :