생성패턴-Builder

2008. 8. 20. 14:21 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Builder]
-----------------------------------------------------------------------------
복잡한 객체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여 서로 다른
표현이라도 이를 생성할 수 있는 동일한 구축 공정을 제공할 수 있도록 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Builder
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>



/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Builder
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Builder
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product() :
  PartA_(0),
  PartB_(0),
  PartC_(0)
 {
 }

 virtual ~Product()
 {
 }

public:
 void SetPartA  (int a) { PartA_= a; }
 void SetPartB  (int b) { PartB_= b; }
 void SetPartC  (int c) { PartC_= c; }

 void Operation (void)
 {
    std::cout << "[Product]" << std::endl
        << "PartA=" << PartA_ << std::endl
        << "PartB=" << PartB_ << std::endl
        << "PartC=" << PartC_ << std::endl
        << std::endl;
 }

private:
 int PartA_;
 int PartB_;
 int PartC_;
};

//// ------------------------------------------------------------------------

class AbstractBuilder
{
public:
 virtual ~AbstractBuilder() {}

public:
 std::auto_ptr<Product> GetResult (void)
 {
  return Product_;
 }
 
 void NewProduct (void)
 {
  Product_.reset ( new Product() );
 }

public:
 virtual void BuildPartA (void)=0;
 virtual void BuildPartB (void)=0;
 virtual void BuildPartC (void)=0;

protected:
 std::auto_ptr<Product> Product_;
};

class ConcreteBuilderA : public AbstractBuilder
{
public:
 virtual void BuildPartA (void) { Product_->SetPartA(1); }
 virtual void BuildPartB (void) { Product_->SetPartB(2); }
 virtual void BuildPartC (void) { Product_->SetPartC(3); }
};

class ConcreteBuilderB : public AbstractBuilder
{
public:
 virtual void BuildPartA (void) { Product_->SetPartA(4); }
 virtual void BuildPartB (void) { Product_->SetPartB(5); }
 virtual void BuildPartC (void) { Product_->SetPartC(6); }
};

//// ------------------------------------------------------------------------

class Director
{
public:
 Director() : Builder_(0) {}
 virtual ~Director()      {}
 
public:
 void SetBuilder (AbstractBuilder* b)
 {
  Builder_ = b;
 }

 void Construct (void)
 {
  Builder_->NewProduct ();
  Builder_->BuildPartA ();
  Builder_->BuildPartB ();
  Builder_->BuildPartC ();
 }

private:
 AbstractBuilder* Builder_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Director               director;
 ConcreteBuilderA       builder_A;
 ConcreteBuilderB       builder_B;
 std::auto_ptr<Product> product;


 director.SetBuilder (&builder_A);
 director.Construct  ();
 product = builder_A.GetResult();
 product->Operation();

 director.SetBuilder (&builder_B);
 director.Construct  ();
 product = builder_B.GetResult();
 product->Operation();

 return 0;
}

-----------------------------------------------------------------------------
[Product]
PartA=1
PartB=2
PartC=3

[Product]
PartA=4
PartB=5
PartC=6

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Abstract Factory]
의도:
구체적 클래스를 정의하지 않고도 서로 관련성이 있거나 독립적인 여러 객체의 군을 생성하기
위한 인터페이스를 제공한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Abstract Factory
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Abstract Factory
//
//
/////////////////////////////////////////////////////////////////////////////
class AbstractProdcutA
{
public:
 AbstractProdcutA ()         {}
 virtual ~AbstractProdcutA() {}
};

class AbstractProdcutB
{
public:
 AbstractProdcutB ()         {}
 virtual ~AbstractProdcutB() {}
};
 
class AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void) = 0;
 virtual AbstractProdcutB* CreateProductB (void) = 0;
};

//// ------------------------------------------------------------------------

class ProdcutA1 : public AbstractProdcutA
{
public:
 ProdcutA1()
 {
  std::cout << "ProdcutA1()" << std::endl;
 }
};
class ProdcutA2 : public AbstractProdcutA
{
public:
 ProdcutA2()
 {
  std::cout << "ProdcutA2()" << std::endl;
 }
};
class ProdcutB1 : public AbstractProdcutB
{
public:
 ProdcutB1()
 {
  std::cout << "ProdcutB1()" << std::endl;
 }
};
class ProdcutB2 : public AbstractProdcutB
{
public:
 ProdcutB2()
 {
  std::cout << "ProdcutB2()" << std::endl;
 }
};

//// ------------------------------------------------------------------------

class ConcreteFactory1 : public AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA1();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB1();
 }
};

class ConcreteFactory2 : public AbstractFactory
{
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA2();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB2();
 }
};

//// ------------------------------------------------------------------------

class Client
{
public:
 void Create (AbstractFactory *f)
 {
  ProdcutA_.reset( f->CreateProductA() );
  ProdcutB_.reset( f->CreateProductB() );
 }

private:
 std::auto_ptr<AbstractProdcutA> ProdcutA_;
 std::auto_ptr<AbstractProdcutB> ProdcutB_;
};



/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Client client;


 std::cout << "by ConcreteFactory1" << std::endl;
 client.Create ( &ConcreteFactory1() );

 std::cout << std::endl;

 std::cout << "by ConcreteFactory2" << std::endl;
 client.Create ( &ConcreteFactory2() );

 return 0;
}
-----------------------------------------------------------------------------
by ConcreteFactory1
ProdcutA1()
ProdcutB1()

by ConcreteFactory2
ProdcutA2()
ProdcutB2()

Posted by 셈말짓기 :

구조패턴-Proxy

2008. 8. 19. 16:04 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Proxy]
의도:
다른 객체에 접근하기 위해 중간 대리 역활을 하는 객체를 둔다.

다른 이름:
Surrogate
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Proxy
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <list>
#include <algorithm>


#define USE_HANDLE 1


#if (USE_HANDLE==1)
/////////////////////////////////////////////////////////////////////////////
//
// Handle
//
/////////////////////////////////////////////////////////////////////////////
template<typename T>
class CRefCountedInstance
{
public:
 CRefCountedInstance ();

public:
 inline void AddRef       (void);
 inline void Release      (void);
 inline void Assign       (T *p);
 inline bool IsReferenced (void);
 inline T*   GetInstance  (void);

private:
 T   *Instance_;
 int  RefCount_;
};

template<typename T>
CRefCountedInstance<T>::CRefCountedInstance () :
 RefCount_ (0),
 Instance_ (0)
{
}

template<typename T>
void CRefCountedInstance<T>::AddRef (void)
{
 RefCount_++;
}

template<typename T>
void CRefCountedInstance<T>::Release (void)
{
 if (RefCount_>0)
 {
  RefCount_--;
 }

 if (RefCount_==0)
 {
  if (Instance_)
  {
   delete Instance_;
  }

  Instance_ = 0;
 }
}

template<typename T>
void CRefCountedInstance<T>::Assign (T *p)
{
 Instance_ = p;
 AddRef ();
}

template<typename T>
bool CRefCountedInstance<T>::IsReferenced (void)
{
 if (RefCount_==0)
  return false;

 return true;
}

template<typename T>
T* CRefCountedInstance<T>::GetInstance (void)
{
 return Instance_;
}

template<typename T>
class Handle
{
public:
 Handle ();
 explicit Handle (T *p);
 Handle (const Handle<T> &copy);
 virtual ~Handle ();

public:
 Handle<T>& operator = (const Handle<T>& rhs);

public:
 inline T& operator*  () const;
 inline T* operator-> () const;
 inline T* Get    (void) const;

private:
 CRefCountedInstance<T>* Rep_;
};

template<typename T>
Handle<T>::Handle () : Rep_(0)
{
}

template<typename T>
Handle<T>::Handle (T *p)
{
 Rep_ = new CRefCountedInstance<T>();
 Rep_->Assign(p);
}

template<typename T>
Handle<T>::Handle (const Handle<T> &copy)
{
 Rep_ = copy.Rep_;

 if (Rep_)
  Rep_->AddRef ();
}

template<typename T>
Handle<T>::~Handle ()
{
 if (Rep_)
 {
  Rep_->Release ();

  if (!Rep_->IsReferenced())
   delete Rep_;
 }
}

template<typename T>
Handle<T>& Handle<T>::operator = (const Handle<T>& rhs)
{
 if (this == &rhs) return *this;

 if (Rep_)
  Rep_->Release ();

 Rep_ = rhs.Rep_;

 if (Rep_)
  Rep_->AddRef ();

 return *this;
}

template<typename T>
T& Handle<T>::operator*() const
{
 return *(Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::operator -> () const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::Get (void) const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}
#endif


/////////////////////////////////////////////////////////////////////////////
//
// Proxy
//
/////////////////////////////////////////////////////////////////////////////
class Subject
{
public:
 virtual ~Subject() {}

public:
 virtual void Request (void) = 0;
 virtual void SetData (int ) = 0;
};

class RealSubject : public Subject
{
public:
 explicit RealSubject (int n) :
  Data_ (n)
 {
  std::cout << "RealSubject::RealSubject(" << Data_ << ")" << std::endl;
 }

 virtual ~RealSubject ()
 {
  std::cout << "RealSubject::~RealSubject(" << Data_ << ")" << std::endl;
 }

public:
 virtual void Request (void)
 {
  std::cout << "RealSubject::Request(): Data_ = " << Data_ << std::endl;
 }

 virtual void SetData (int n)
 {
  Data_ = n;
 }

private:
 int Data_;
};


#if (USE_HANDLE==1)
class Proxy :
 public Subject
{
public:
 Proxy() : SubjectData_(0)
 {
 }

 explicit Proxy (int n) :
  SubjectData_ (n)
 {
 }

 Proxy (const Proxy &copy)
 {
  const_cast<Proxy&>(copy).Load();

  SubjectData_ = copy.SubjectData_;
  Subject_     = copy.Subject_;
 }

 virtual ~Proxy () {}

public:
 virtual void Request (void)
 {
  GetSubject()->Request();
 }

 virtual void SetData (int n)
 {
  GetSubject()->SetData(n);
 }

private:
 Subject* GetSubject (void)
 {
  if (Subject_.Get()==0)
  {
   Handle<Subject> s ( new RealSubject(SubjectData_) );
   Subject_ = s;
  }

  return Subject_.Get();
 }

public:
 void Load (void)
 {
  GetSubject();
 }

public:
 Proxy& operator = (const Proxy& rhs)
 {
  if (this == &rhs) return *this;

  const_cast<Proxy&>(rhs).Load();

  SubjectData_ = rhs.SubjectData_;
  Subject_     = rhs.Subject_;

  return *this;
 }

private:
 Handle<Subject>  Subject_;
 int              SubjectData_;
};
#else
class Proxy :
 public Subject
{
public:
 Proxy() :
  SubjectData_(0), 
  Subject_    (0)
 {
 }

 explicit Proxy (int n) :
 SubjectData_ (n),
  Subject_     (0)
 {
 }

 virtual ~Proxy ()
 {
  if (Subject_)
   delete Subject_;
 }

public:
 virtual void Request (void)
 {
  GetSubject()->Request();
 }

 virtual void SetData (int n)
 {
  GetSubject()->SetData(n);
 }

private:
 Subject* GetSubject (void)
 {
  if (Subject_==0)
  {
   Subject_ = new RealSubject(SubjectData_);
  }
  return Subject_;
 }

private:
 Subject         *Subject_;
 int              SubjectData_;
};
#endif


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
#if (USE_HANDLE==1)
 std::cout << "(USE_HANDLE==1)" << std::endl << std::endl;

 Proxy a(1);
 Proxy b;
 Proxy c;


 std::cout << "a.Load();" << std::endl;
 //a.Load();
 std::cout << std::endl;


 std::cout << "b=a;" << std::endl;
 b=a;
 std::cout << std::endl;


 std::cout << "a.Request ();" << std::endl;
 a.Request ();
 std::cout << std::endl;


 std::cout << "a.SetData (2);" << std::endl;
 a.SetData (2);
 std::cout << std::endl;


 std::cout << "b.Request ();" << std::endl;
 b.Request ();
 std::cout << std::endl;


 std::cout << "c=a" << std::endl;
 c=a;
 std::cout << "c.Request()" << std::endl;
 c.Request ();
 std::cout << std::endl;
#else
 std::cout << "(USE_HANDLE==0)" << std::endl << std::endl;

 Proxy       a(1);
 RealSubject b(2);


 std::cout << std::endl;

 std::cout << "a.Request()" << std::endl;
 a.Request (); // late creating instance
 std::cout << std::endl;

 std::cout << "a.Request()" << std::endl;
 b.Request ();
 std::cout << std::endl;
#endif

 return 0;
}
-----------------------------------------------------------------------------
(USE_HANDLE==1)

a.Load();
RealSubject::RealSubject(1)

b=a;

a.Request ();
RealSubject::Request(): Data_ = 1

a.SetData (2);

b.Request ();
RealSubject::Request(): Data_ = 2

c=a
c.Request()
RealSubject::Request(): Data_ = 2

RealSubject::~RealSubject(2)
-----------------------------------------------------------------------------
(USE_HANDLE==0)

RealSubject::RealSubject(2)

a.Request()
RealSubject::RealSubject(1)
RealSubject::Request(): Data_ = 1

a.Request()
RealSubject::Request(): Data_ = 2

RealSubject::~RealSubject(2)
RealSubject::~RealSubject(1)

Posted by 셈말짓기 :

구조패턴-Flyweight

2008. 8. 19. 00:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Flyweight]
의도:
대규모의 미세한 객체들을 효과적으로 사용하기 위해서는 공유 개념을 도입
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Flyweight
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <list>
#include <algorithm>


/////////////////////////////////////////////////////////////////////////////
//
// Flyweight
//
/////////////////////////////////////////////////////////////////////////////
class Flyweight
{
public:
 virtual ~Flyweight() {}
public:
 virtual void Operation (void) = 0;
};

class ConcreteFlyweight : public Flyweight
{
public:
 ConcreteFlyweight (std::string s, int n) :
  Key_   (n),
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << "(" << Key_ << ")" << std::endl;
 }

private:
 int         Key_;
 std::string Value_;
};

class UnsharedConcreteFlyweight : public Flyweight
{
public:
 UnsharedConcreteFlyweight (std::string s) :
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << std::endl;
 }

private:
 std::string Value_;
};

//// ------------------------------------------------------------------------

class FlyweightFactory
{
private:
 struct PoolDeleter
 {
 public:
  PoolDeleter() : Count_(0) {}
 public:
  void operator()(std::pair<int,Flyweight*> i)
  {
   Flyweight *p = i.second;

   if (p)
   {
    Count_++;
    delete p;
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 virtual ~FlyweightFactory ()
 {
  int Count;

  Count = std::for_each(Pool_.begin(), Pool_.end(), PoolDeleter());
  std::cout << "~FlyweightFactory(): [ConcreteFlyweight] deleting count="
            << Count
            << std::endl
            << std::endl;
 }

public:
 Flyweight* GetFlyweight (std::string value, int key)
 {
  Flyweight*  f;

  if ( Pool_.end() == Pool_.find (key) )
  {
   f = new ConcreteFlyweight (value, key);
   Pool_[key] = f;
  }
  else
  {
   f = Pool_[key];
  }

  return f;
 }

 Flyweight* GetUnsharedFlyweight (std::string value)
 {
  Flyweight* f;

  f = new UnsharedConcreteFlyweight ( value );

  return f;
 }

private:
 std::map <int,Flyweight*> Pool_;
};

//// ------------------------------------------------------------------------

class Context
{
private:
 template<class T>
 struct OperationCaller : public std::unary_function<T, void>
 {
 public:
  void operator()(T ptr)
  {
   if (ptr)
    ptr->Operation();
  }
 };

 template<class T>
 struct ListDeleter : public std::unary_function<T, void>
 {
 public:
  ListDeleter() : Count_(0) {}
 public:
  void operator()(T ptr)
  {
   if (ptr)
   {
    if (dynamic_cast<UnsharedConcreteFlyweight*>(ptr))
    {
     Count_++;
     delete ptr;
    }
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 ~Context ()
 {
  int Count;

  Count = std::for_each(List_.begin(), List_.end(), ListDeleter<Flyweight*>());
  std::cout << "~Context(): [UnsharedConcreteFlyweight] deleting count="
            << Count
            << std::endl;
 }

public:
 void Add (std::string s, int n=0)
 {
  if (n)
   List_.push_back ( Factory_.GetFlyweight (s, n) );
  else
   List_.push_back ( Factory_.GetUnsharedFlyweight (s) );
 }

 void Operation (void)
 {
  std::for_each(List_.begin(), List_.end(), OperationCaller<Flyweight*>());  

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

private:
 std::list<Flyweight*> List_;
 FlyweightFactory      Factory_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Context context;

 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );

 context.Operation ();

 return 0;
}
-----------------------------------------------------------------------------
one(1)
two
one(1)
two
one(1)
two
one(1)
two
one(1)
two

~Context(): [UnsharedConcreteFlyweight] deleting count=5
~FlyweightFactory(): [ConcreteFlyweight] deleting count=1


Posted by 셈말짓기 :

구조패턴-Facade

2008. 8. 18. 21:03 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Facade]
의도:
서브시스템을 합성하는 다수의 객체들의 인터페이스 집합에 대해 일관된 하나의 인터페이스를
제공할 수 있게 한다. Facade는 서브시스템을 사용하기 쉽게 하기 위한 포괄적 개념의 인터
페이스를 정의 한다.
-----------------------------------------------------------------------------/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Facade
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Subsystem
//
/////////////////////////////////////////////////////////////////////////////
class SubsystemA
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemA::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemA::OperationB()" << std::endl;
 }
};

class SubsystemB
{
public:
 void Operation (void)
 {
  std::cout << "\tSubsystemB::Operation()" << std::endl;
 }
};

class SubsystemC
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemC::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemC::OperationB()" << std::endl;
 }
 void OperationC (void)
 {
  std::cout << "\tSubsystemC::OperationC()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Facade
//
/////////////////////////////////////////////////////////////////////////////
class Facade
{
public:
 void OperationA (void)
 {
  std::cout << "Facade::OperationA()" << std::endl;
  A_.OperationA();
  B_.Operation ();
  C_.OperationA();
  std::cout << std::endl;
 }

 void OperationB (void)
 {
  std::cout << "Facade::OperationB()" << std::endl;
  A_.OperationB();
  C_.OperationB();
  C_.OperationC();
  std::cout << std::endl;
 }

private:
 SubsystemA A_;
 SubsystemB B_;
 SubsystemC C_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Facade f;

 f.OperationA();
 f.OperationB();

 return 0;
}
-----------------------------------------------------------------------------Facade::OperationA()
        SubsystemA::OperationA()
        SubsystemB::Operation()
        SubsystemC::OperationA()

Facade::OperationB()
        SubsystemA::OperationB()
        SubsystemC::OperationB()
        SubsystemC::OperationC()

Posted by 셈말짓기 :

구조패턴-Decorator

2008. 8. 18. 20:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Decorator]
의도:
객체에 동적으로 새로운 서비스를 추가할 수 있게 한다. Decorator패턴은 기능의 추가를
위해서 서브클래스를 생성하는 것보다 융통성 있는 방법을 제공한다.

다른 이름:
Wrapper
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Decorator
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Decorator
//
//
/////////////////////////////////////////////////////////////////////////////
class Component
{
public:
 virtual ~Component() {}

public:
 virtual void Operation (void) = 0;
};

class ConcreteComponent : public Component
{
public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteComponent::Operation()" << std::endl;
 }
};

class Decorator : public Component
{
public:
 explicit Decorator (Component* p) :
  Component_(p)
 {
 }

public:
 virtual void Operation (void)
 {
  if (Component_.get())
   Component_->Operation ();
 }

private:
 std::auto_ptr<Component> Component_;
};

class ConcreteDecoratorA : public Decorator
{
public:
 explicit ConcreteDecoratorA (Component* p) :
  Decorator(p)
 {
 }

public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorA::Operation()" << std::endl;
 }
};

class ConcreteDecoratorB : public Decorator
{
public:
 explicit ConcreteDecoratorB (Component* p) :
  Decorator(p)
 {
 }
public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorB::Operation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Component> p;
 
 p.reset( new ConcreteDecoratorB (
              new ConcreteDecoratorA (
                  new ConcreteComponent())) );

 p->Operation ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteComponent::Operation()
ConcreteDecoratorA::Operation()
ConcreteDecoratorB::Operation()

Posted by 셈말짓기 :

구조패턴-Bridge

2008. 8. 18. 17:38 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Bridge]
의도:
구현과 추상화 개념을 분리하려는 것이다. 이로써 구현 자체도 하나의 추상화 개념으로 다양한
변형이 가능해지고, 구현과 독립적으로 인터페이스도 다양함을 가질 수 있게 된다.

다른 이름:
Handle/body
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Bridge
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Bridge
//
/////////////////////////////////////////////////////////////////////////////
class Implementor
{
public:
 virtual ~Implementor () {}
public:
 virtual void OperationImp (void) = 0;
};

class ConcreteImplementorA : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorA::OperationImp()" << std::endl;
 }
};

class ConcreteImplementorB : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorB::OperationImp()" << std::endl;
 }
};

class ImplementorFactory
{
private:
 ImplementorFactory(void) : Env_(0) {};
public:
 static ImplementorFactory* Instance (void)
 {
  if (0==Instance_)
  {
   Instance_ = new ImplementorFactory();
  }

  return Instance_;
 }

private:
 static ImplementorFactory* Instance_;

public:
 Implementor* CreateImplementor (void)
 {
  Implementor* p;
 
  if (Env_==0)
   p = new ConcreteImplementorA();
  else
   p = new ConcreteImplementorB();

  return p;
 }

public:
 void SetEnv (int e)
 {
  Env_ = e;
 }

 int  GetEnv (void)
 {
  return Env_;
 }

private:
 int Env_;
};

ImplementorFactory* ImplementorFactory::Instance_ = 0;

class Abstraction
{
public:
 Abstraction () : Imp_(0)
 {
 }

public:
 virtual void Operation (void)
 {
  GetImp ()->OperationImp();
 }

private:
 Implementor* GetImp (void)
 {
  if (Imp_==0)
  {
   Imp_ = ImplementorFactory::Instance()->CreateImplementor ();
  }

  return Imp_;
 }

private:
 Implementor *Imp_;
};

class RefinedAbstraction : public Abstraction
{
public:
 virtual void RefinedOperation (void)
 {
  Abstraction::Operation();
  std::cout<< "RefinedAbstraction::RefinedOperation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<RefinedAbstraction> p;


 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 std::cout << std::endl;
 ImplementorFactory::Instance()->SetEnv (1);

 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteImplementorA::OperationImp()
RefinedAbstraction::RefinedOperation()

ConcreteImplementorB::OperationImp()
RefinedAbstraction::RefinedOperation()

Posted by 셈말짓기 :

Reference-Counting

2008. 8. 18. 13:24 from 셈말짓기/C and C++

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

#include <iostream>

/////////////////////////////////////////////////////////////////////////////
//
// Handle
//
/////////////////////////////////////////////////////////////////////////////
template<typename T>
class CRefCountedInstance
{
public:
 CRefCountedInstance ();

public:
 inline void AddRef       (void);
 inline void Release      (void);
 inline void Assign       (T *p);
 inline bool IsReferenced (void);
 inline T*   GetInstance  (void);

private:
 T   *Instance_;
 int  RefCount_;
};

template<typename T>
CRefCountedInstance<T>::CRefCountedInstance () :
 RefCount_ (0),
 Instance_ (0)
{
}

template<typename T>
void CRefCountedInstance<T>::AddRef (void)
{
 RefCount_++;
}

template<typename T>
void CRefCountedInstance<T>::Release (void)
{
 if (RefCount_>0)
 {
  RefCount_--;
 }

 if (RefCount_==0)
 {
  if (Instance_)
  {
   delete Instance_;
  }

  Instance_ = 0;
 }
}

template<typename T>
void CRefCountedInstance<T>::Assign (T *p)
{
 Instance_ = p;
 AddRef ();
}

template<typename T>
bool CRefCountedInstance<T>::IsReferenced (void)
{
 if (RefCount_==0)
  return false;

 return true;
}

template<typename T>
T* CRefCountedInstance<T>::GetInstance (void)
{
 return Instance_;
}

template<typename T>
class Handle
{
public:
 Handle ();
 explicit Handle (T *p);
 Handle (const Handle<T> &copy);
 ~Handle ();

public:
 Handle<T>& operator = (const Handle<T>& rhs);

public:
 inline T& operator*  () const;
 inline T* operator-> () const;
 inline T* Get    (void) const;

private:
 CRefCountedInstance<T>* Rep_;
};

template<typename T>
Handle<T>::Handle () : Rep_(0)
{
}

template<typename T>
Handle<T>::Handle (T *p)
{
 Rep_ = new CRefCountedInstance<T>();
 Rep_->Assign(p);
}

template<typename T>
Handle<T>::Handle (const Handle<T> &copy)
{
 Rep_ = copy.Rep_;

 if (Rep_)
  Rep_->AddRef ();
}

template<typename T>
Handle<T>::~Handle ()
{
 if (Rep_)
 {
  Rep_->Release ();

  if (!Rep_->IsReferenced())
   delete Rep_;
 }
}

template<typename T>
Handle<T>& Handle<T>::operator = (const Handle<T>& rhs)
{
 if (this == &rhs) return *this;

 if (Rep_)
  Rep_->Release ();

 Rep_ = rhs.Rep_;

 if (Rep_)
  Rep_->AddRef ();

 return *this;
}

template<typename T>
T& Handle<T>::operator*() const
{
 return *(Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::operator -> () const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::Get (void) const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
/////////////////////////////////////////////////////////////////////////////
class Object
{
public:
 explicit Object(int n=0) : Data_(n)
 {
  std::cout << "Object(" << Data_ << ")" << std::endl;
 }

public:
 virtual ~Object()
 {
  std::cout << "~Object(" << Data_ << ")" << std::endl;
 }

public:
 int Data_;
};

Handle<Object> Test (Handle<Object> h)
{
 if (h.Get())
  h->Data_ = 3;

 return h;
}


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Handle<Object> p1( new Object(1) );
 Handle<Object> p2( new Object(2) );
 Handle<Object> p3;
 Handle<Object> p4;


 std::cout << std::endl;


 std::cout << "p2 = p1;" << std::endl;
 p2 = p1;
 std::cout << std::endl;


 std::cout << "p3 = p1;" << std::endl;
 p3 = p1;
 std::cout << std::endl;


 std::cout << "p4 = Test (p3);" << std::endl;
 p4 = Test (p3);

 std::cout << "p1->Data_ = " << p1->Data_ << std::endl;
 std::cout << "p2->Data_ = " << p2->Data_ << std::endl;
 std::cout << "p3->Data_ = " << p3->Data_ << std::endl;
 std::cout << "p4->Data_ = " << p3->Data_ << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Object(1)
Object(2)

p2 = p1;
~Object(2)

p3 = p1;

p4 = Test (p3);
p1->Data_ = 3
p2->Data_ = 3
p3->Data_ = 3
p4->Data_ = 3
~Object(3)

Posted by 셈말짓기 :

구조패턴-Adapter

2008. 8. 17. 01:22 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Adapter]
의도:
클래스의 인터페이스를 클라이언트가 기대하는 형태의 인터페이스로 변환한다.
어댑터 패턴은 서로 일치하지 않는 인터페이스를 갖는 클래스들을 함께 작동 시킨다.

다른 이름:
Wrapper
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Adapter
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Adapter-1
//
//
/////////////////////////////////////////////////////////////////////////////
class Target
{
public:
 virtual ~Target() {}
public:
 virtual void Request (void) = 0;
};

class Adaptee
{
public:
 void SpecificRequest (void)
 {
  std::cout << "Adaptee::SpecificRequest()" << std::endl;
 }
};

class Adapter_1 :
 public  Target,
 private Adaptee
{
public:
 virtual void Request (void)
 {
  std::cout << "Adaptee::SpecificRequest()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Adapter-2
//
//
/////////////////////////////////////////////////////////////////////////////
class Adapter_2 :
 public Target
{
public:
 virtual void Request (void)
 {
  Adaptee_.SpecificRequest();
 }
private:
 Adaptee Adaptee_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Target> t1 ( new Adapter_1() );
 std::auto_ptr<Target> t2 ( new Adapter_2() );

 t1->Request ();
 t2->Request ();

 return 0;
}
-----------------------------------------------------------------------------
Adaptee::SpecificRequest()
Adaptee::SpecificRequest()

Posted by 셈말짓기 :

행위패턴-Iterator

2008. 8. 16. 18:19 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Iterator]
의도:
복합 객체 요소들의 내부 표현 방식을 공개하지 않고도 순차적으로 접근할 수 있는 방법을 제공
한다.

다른 이름:
Cursor

설명:
STL의 컨테이너들에 대한 iterator를 생각하면 된다.
-----------------------------------------------------------------------------

GoF에서는 Iterator에 대한 인터페이스를 아래와 같이 표현하고 있다.
template<class Item>
class Iterator
{
public:
 virtual void First()        = 0;
 virtual void Next()         = 0;
 virtual bool IsDone() const = 0;
protected:
 Iterator() {};
};

Posted by 셈말짓기 :

행위패턴-State

2008. 8. 16. 17:59 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[State]
의도:
객체 자신의 내부 상태에 따라 행위를 변경하도록 한다. 객체가 클래스를 바꾸는 것처럼 보일
수 있다.

다른 이름:
Object for State

설명:
FSM(Finite State Machine)를 구현함에 있어서 State패턴을 이용한다.
-----------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - State
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// State
//
/////////////////////////////////////////////////////////////////////////////
class Context;

class State
{
public:
 virtual ~State() {}
public:
 virtual void Handle      (Context*) {}
protected:
 virtual void ChangeState (Context*, State*);
};

//// ------------------------------------------------------------------------

class ConcreteStateA : public State
{
public:
 virtual void Handle(Context* c);
};

class ConcreteStateB : public State
{
public:
 virtual void Handle(Context* c);
};

class ConcreteStateC : public State
{
public:
 virtual void Handle(Context* c);
};

void ConcreteStateA::Handle(Context* c)
{
 std::cout << "ConcreteStateA::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateB());
}

void ConcreteStateB::Handle(Context* c)
{
 std::cout << "ConcreteStateB::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateC());
}

void ConcreteStateC::Handle(Context* c)
{
 std::cout << "ConcreteStateC::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateA());
}

//// ------------------------------------------------------------------------

class Context
{
public:
 friend class State;
public:
 Context () : State_(0)
 {
  State_ = new ConcreteStateA();
 }

 virtual ~Context ()
 {
  if (State_)
   delete State_;
 }

public:
 void Request (void)
 {
  if (State_)
  {
   State_->Handle(this);
  }
 }

protected:
 void ChangeState (State *s)
 {
  if (State_)
  {
   delete State_;
  }

  State_ = s;
 }

private:
 State *State_;
};

//// ------------------------------------------------------------------------

void State::ChangeState (Context* c, State* s)
{
 c->ChangeState (s);
}


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Context context;

 context.Request();
 context.Request();
 context.Request();

 context.Request();
 context.Request();
 context.Request();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteStateA::Handle()
ConcreteStateB::Handle()
ConcreteStateC::Handle()
ConcreteStateA::Handle()
ConcreteStateB::Handle()
ConcreteStateC::Handle()


Posted by 셈말짓기 :

행위패턴-Observer

2008. 8. 16. 17:17 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Observer]
의도:
일대다의 관련성을 갖는 객체들의 경우 한 객체의 상태가 변하면 다른 모든 객체에 그 사항을
알리고 필요한 수정이 자동으로 이루어지도록 할 수 있어야 한다.

다른 이름:
Dependent, Publish-Subject

설명:
MFC의 CView::OnUpdate(), CDocument::UpdateAllViews()와 같은 개념으로 MVC 모델에서
One-Document에 Multi-View모델을 생각하면 쉽다. 이 때 Document는 Subject이고 View는
Observer이다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Observer
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <list>
#include <algorithm>


/////////////////////////////////////////////////////////////////////////////
//
// Observer
//
/////////////////////////////////////////////////////////////////////////////
class Subject;

class Observer
{
public:
 virtual ~Observer() {}

public:
 virtual void Update (Subject* s) = 0;
};

class Subject
{
public:
 virtual ~Subject() {}

public:
 void Attach (Observer *o)
 {
  Observers_.push_back (o);
 }
 void Detach (Observer *o)
 {
  std::list<Observer*>::iterator i;

  i = std::find (Observers_.begin(), Observers_.end(), o);
  if (i!=Observers_.end())
  {
   Observers_.erase (i);
  }
 }
 void Notify (void)
 {
  std::list<Observer*>::iterator i;

  for (i=Observers_.begin(); i!=Observers_.end(); i++)
  {
   (*i)->Update (this);
  } 
 }

private:
 std::list<Observer*> Observers_;
};

////-------------------------------------------------------------------------

class ConcreteSubject : public Subject
{
public:
 void SetState (std::string s)
 {
  State_ = s;

  Notify ();
 }

 std::string GetState (void) const
 {
  return State_;
 }

private:
 std::string State_;
};

class ConcreteObserverA : public Observer
{
public:
 explicit ConcreteObserverA(ConcreteSubject* s) : Subject_(s)
 {
  Subject_->Attach (this);
 }
 virtual ~ConcreteObserverA()
 {
  Subject_->Detach (this);
 }

public:
 virtual void Update (Subject* s)
 {
  if (s==Subject_)
  {
   std::cout << "ConcreteObserverA::Update(): Subject_->GetState()="
             << Subject_->GetState().c_str()
       << std::endl;
  }
 }

protected:
 ConcreteSubject *Subject_;
};

class ConcreteObserverB : public Observer
{
public:
 explicit ConcreteObserverB (ConcreteSubject* s) : Subject_(s)
 {
  Subject_->Attach (this);
 }
 virtual ~ConcreteObserverB()
 {
  Subject_->Detach (this);
 }

public:
 virtual void Update (Subject* s)
 {
  if (s==Subject_)
  {
   std::cout << "ConcreteObserverB::Update(): Subject_->GetState()="
             << Subject_->GetState().c_str()
       << std::endl;
  }
 }

protected:
 ConcreteSubject *Subject_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteSubject   subject;
 ConcreteObserverA observerA(&subject);
 ConcreteObserverB observerB(&subject);

 subject.SetState ("one");
 subject.SetState ("two");
 subject.SetState ("three");

 return 0;
}
-----------------------------------------------------------------------------
ConcreteObserverA::Update(): Subject_->GetState()=one
ConcreteObserverB::Update(): Subject_->GetState()=one
ConcreteObserverA::Update(): Subject_->GetState()=two
ConcreteObserverB::Update(): Subject_->GetState()=two
ConcreteObserverA::Update(): Subject_->GetState()=three
ConcreteObserverB::Update(): Subject_->GetState()=three

Posted by 셈말짓기 :

행위패턴-Memento

2008. 8. 16. 12:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Memento]
의도:
캡슐화를 위배하지 않으면서 객체의 내부 상태를 파악하고 표현함으로써 객체의 상태를 저장해
둔 상태로 다시 복구 할 수 있게 한다.

다른 이름:
Token
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Memento
//
/////////////////////////////////////////////////////////////////////////////

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

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



/////////////////////////////////////////////////////////////////////////////
//
// Utility
//
/////////////////////////////////////////////////////////////////////////////
template<class T>
struct deleteobject_functor : public std::unary_function<T, void>
{
public:
 void operator()(T ptr)
 {
  delete ptr;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Memento
//
/////////////////////////////////////////////////////////////////////////////
typedef std::string State;

class Memento
{
private:
 friend class Originator;

private:
 Memento(void) : State_("empty")
 {
 }

public:
 State GetState (void) const
 {
  return State_;
 }

 void SetState (State s)
 {
  State_ = s;
 }

private:
 State State_;
};

class Originator
{
public:
 Originator (void) : State_("empty")
 {
 }

public:
 Memento* CreateMemento (void)
 {
  Memento *m;

  m = new Memento();
  m->SetState (State_);

  return m;
 }

 void SetMemento (const Memento* m)
 {
  State_ = m->GetState ();

  delete m;
 }

 void SetState (std::string s)
 {
  State_ = s;
 }

private:
 State State_;

public:
 friend std::ostream& operator<< (std::ostream&, const Originator&);
};

class CareTaker
{
public:
 virtual ~CareTaker ()
 {
  std::for_each(History_.begin(), History_.end(), deleteobject_functor<Memento*>());
 }

public:
 void Push (Memento* m)
 {
  History_.push_back (m);
 }

 Memento* Pop (void)
 {
  Memento* m = 0;

  if (!History_.empty())
  {
   m=History_.back();
   History_.pop_back();
  }

  return m;
 }

private:
 std::deque <Memento*> History_;
};

////-------------------------------------------------------------------------

std::ostream& operator<< (std::ostream& os, const Originator &org)
{
 os << "Originator's State=" << org.State_.c_str();

 return os;
}

/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Originator originator;
 CareTaker  caretaker;


 originator.SetState ("first");
 std::cout << originator << std::endl;

 std::cout << std::endl;

 caretaker.Push ( originator.CreateMemento () );
 originator.SetState ("second");
 std::cout << originator << std::endl;

 caretaker.Push ( originator.CreateMemento () );
 originator.SetState ("third");
 std::cout << originator << std::endl;

 std::cout << std::endl;

 originator.SetMemento ( caretaker.Pop () );
 std::cout << originator << std::endl;

 originator.SetMemento ( caretaker.Pop () );
 std::cout << originator << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Originator's State=first

Originator's State=second
Originator's State=third

Originator's State=second
Originator's State=first


Posted by 셈말짓기 :
Posted by 셈말짓기 :

행위패턴-Mediator

2008. 8. 16. 00:19 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Mediator]
의도:
객체들 간의 상호작용을 캡슐화하여 하나의 객체 안에 정의한다. Mediator 패턴은 각 객체가
관련성을 갖는 다른 객체에 대한 참조 관계를 직접 정의하기보다는 이를 독립된 다른 객체가
관리하게 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Mediator
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Mediator
//
//
/////////////////////////////////////////////////////////////////////////////
class Colleague;

class Mediator
{
public:
 virtual ~Mediator () {}
public:
 virtual void OnNotify (Colleague *) {}
};

class Colleague
{
public:
 Colleague (Mediator* m) : Mediator_(m) {}
 virtual ~Colleague () {}
public:
 virtual void Notify ()
 {
  if (Mediator_)
  {
   Mediator_->OnNotify (this);
  }
 }

protected:
 Mediator* Mediator_;
};

////-------------------------------------------------------------------------

class ConcreteColleague1 : public Colleague
{
public:
 ConcreteColleague1 (Mediator* m) : Colleague (m) {}

public:
 void Act1 (void)
 {
  Notify ();
 }
};

class ConcreteColleague2 : public Colleague
{
public:
 ConcreteColleague2 (Mediator* m) : Colleague (m) {}

public:
 void Act2 (void)
 {
  Notify ();
 }
};

class ConcreteMediator : public Mediator
{
public:
 void Init (void)
 {
  Colleague1_.reset ( new ConcreteColleague1(this) );
  Colleague2_.reset ( new ConcreteColleague2(this) );
 }

 void Run (void)
 {
  Colleague1_->Act1 ();
  Colleague2_->Act2 ();
 }

 virtual void OnNotify (Colleague *c)
 {
  if      (c==Colleague1_.get())
  {
   std::cout << "ConcreteMediator::OnNotify() = Colleague1_" << std::endl;
  }
  else if (c==Colleague2_.get())
  {
   std::cout << "ConcreteMediator::OnNotify() = Colleague2_" << std::endl;
  }
 }

private:
 std::auto_ptr<ConcreteColleague1> Colleague1_;
 std::auto_ptr<ConcreteColleague2> Colleague2_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteMediator mediator;

 mediator.Init ();
 mediator.Run  ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteMediator::OnNotify() = Colleague1_
ConcreteMediator::OnNotify() = Colleague2_

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Template Method]
의도:
오퍼레이션에 알고리즘의 기본 골격 구조를 정의하고 구체적인 단계는 서브클래스에 정의한다.
Template Method 클래스의 서브클래스는 알고리즘의 구조를 변경하지 않고 알고리즘 처리
단계들을 재정의 할 수 있다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Template Method
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Template Method
//
/////////////////////////////////////////////////////////////////////////////
class AbstractClass
{
public:
 virtual ~AbstractClass()
 {
 }

public:
 void TemplateMethod (void)
 {
  std::cout << "AbstractClass::TemplateMethod()" << std::endl;

  std::cout << "\t";
  PrimitiveOperation1();

  std::cout << "\t";
  PrimitiveOperation2();

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

 virtual void PrimitiveOperation1 (void)
 {
 }

 virtual void PrimitiveOperation2 (void)
 {
 }
};

class ConcreteClassA : public AbstractClass
{
public:
 virtual void PrimitiveOperation1 (void)
 {
  std::cout << "ConcreteClassA::PrimitiveOperation1()" << std::endl;
 }

 virtual void PrimitiveOperation2 (void)
 {
  std::cout << "ConcreteClassA::PrimitiveOperation2()" << std::endl;
 }
};

class ConcreteClassB : public AbstractClass
{
public:
 virtual void PrimitiveOperation1 (void)
 {
  std::cout << "ConcreteClassB::PrimitiveOperation1()" << std::endl;
 }

 virtual void PrimitiveOperation2 (void)
 {
  std::cout << "ConcreteClassB::PrimitiveOperation2()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<AbstractClass> a;

 a.reset ( new ConcreteClassA() );
 a->TemplateMethod ();

 a.reset ( new ConcreteClassB() );
 a->TemplateMethod ();

 return 0;
}
-----------------------------------------------------------------------------AbstractClass::TemplateMethod()
        ConcreteClassA::PrimitiveOperation1()
        ConcreteClassA::PrimitiveOperation2()

AbstractClass::TemplateMethod()
        ConcreteClassB::PrimitiveOperation1()
        ConcreteClassB::PrimitiveOperation2()


Posted by 셈말짓기 :

§ GoF의 디자인 패턴이란?
     먼저, GoF란 Design Patterns: Elements of Reusable Object-Oriented Software이란 책을 쓰신
   Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 네명의 사람들을 가리키는 Gang
   of Four로 표현되어지는데 이를 약어로 GoF라 쓰고있다.

     GoF에 나오는 디자인 패턴이란 소프트웨어 개발자들이 소프트웨어를 구현을 할 때 이루어지는
   구조들을 정리한 내용이다.  

     개발자들이 알게 모르게 자주 쓰는 기법들을 어휘화 해서 정리하여 이름을 붙인 패턴들이 GoF에는
   총 23개가  정리 되어있는데 생성패턴은 5개, 구조패턴은 7개, 행위패턴은 11개로 이루어 져있다.

1. 생성패턴(Creational Patterns)
   Abstract Factory groups object factories that have a common theme.
   Builder constructs complex objects by separating construction and representation.
   Factory Method creates objects without specifying the exact class to create.
   Prototype creates objects by cloning an existing object.
   Singleton restricts object creation for a class to only one instance.

2. 구조패턴(Structural Patterns)
   Adapter allows classes with incompatible interfaces to work together by wrapping its own
                interface around that of an already existing class.
   Bridge decouples an abstraction from its implementation so that the two can vary independently.
   Composite composes one-or-more similar objects so that they can be manipulated as one object.
   Decorator dynamically adds/overrides behaviour in an existing method of an object.
   Facade provides a simplified interface to a large body of code.
   Flyweight reduces the cost of creating and manipulating a large number of similar objects.
   Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

3. 행위패턴(Behavioral Patterns)
   Chain of Responsibility delegates commands to a chain of processing objects.
   Command creates objects which encapsulate actions and parameters.
   Interpreter implements a specialized language.
   Iterator accesses the elements of an object sequentially without exposing its underlying  
                representation.
   Mediator allows loose coupling between classes by being the only class that has detailed
                   knowledge of their methods.
   Memento provides the ability to restore an object to its previous state (undo).
   Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
   State allows an object to alter its behavior when its internal state changes.
   Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
   Template Method defines the skeleton of an algorithm as an abstract class, allowing its subclasses
                                to provide concrete behavior.
   Visitor separates an algorithm from an object structure by moving the hierarchy of methods into
                one object.

사용자 삽입 이미지

사용자 삽입 이미지

출저: http://www.mcdonaldland.info/2007/11/28/40/



Posted by 셈말짓기 :

행위패턴-Strategy

2008. 8. 15. 18:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Strategy]
의도:
다양한 알고리즘이 존재하면 이들 각각을 하나의 클래스로 캡슐화하여 알고리즘의 대체가 가능
하도록 한다. Strategy패턴을 이용하면 클라이언트와 독립적인 다양한 알고리즘으로 변형할 수
있다. 알고리즘을 바구더라도 클라이언트는 아무런 변경을 할 필요가 없다.

다른 이름:
Policy

참고:
Policy-based design이 Strategy을 이용한 디자인 방법이다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Strategy
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// Strategy
//
//
/////////////////////////////////////////////////////////////////////////////
class Strategy
{
public:
 virtual ~Strategy() {}
public:
 virtual void AlgorithmInterface(void) = 0;
};

template <typename Strategy>
class Context
{
public:
 void operator() ()
 {
  Strategy_.AlgorithmInterface ();
 }

private:
 Strategy Strategy_;
};

class ContextByRunTime
{
public:
 explicit ContextByRunTime (Strategy *s) :
  Strategy_ (s)
 {
 }

public:
 void operator() ()
 {
  Strategy_->AlgorithmInterface ();
 }

private:
 Strategy *Strategy_;
};

class ConcreteStrategyA : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyA::AlgorithmInterface()" << std::endl;
 }
};

class ConcreteStrategyB : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyB::AlgorithmInterface()" << std::endl;
 }
};

class ConcreteStrategyC : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyC::AlgorithmInterface()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteStrategyA s1;
 ConcreteStrategyB s2;
 ConcreteStrategyC s3;

 ContextByRunTime cr1(&s1);
 ContextByRunTime cr2(&s2);
 ContextByRunTime cr3(&s3);

 Context<ConcreteStrategyA> cc1;
 Context<ConcreteStrategyB> cc2;
 Context<ConcreteStrategyC> cc3;

 std::cout << "by run-time" << std::endl;
 cr1();
 cr2();
 cr3();

 std::cout << std::endl;

 std::cout << "by compile-time" << std::endl;
 cc1();
 cc2();
 cc3();

 return 0;
}
-----------------------------------------------------------------------------
by run-time
ConcreteStrategyA::AlgorithmInterface()
ConcreteStrategyB::AlgorithmInterface()
ConcreteStrategyC::AlgorithmInterface()

by compile-time
ConcreteStrategyA::AlgorithmInterface()
ConcreteStrategyB::AlgorithmInterface()
ConcreteStrategyC::AlgorithmInterface()


Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Chain Of Responsibility]
의도:
메시지를 보내는 객체와 이를 받아 처리하는 객체들 간의 결합도를 없애기 위한 패턴이다.
하나의 요청에 대한 처리가 반드시 한 객체에서만 이루어지지 않고, 여러 객체에게 그 처리의
기회를 주려는 것이다. 즉, 이 패턴에서는 하나의 서비스 처리를 여러 객체에 나눌 수 있도록
한다. 메시지를 수신하여 처리를 담당할 객체들을 하나의 연결 고리로 만들고, 실제로 요청을
처리하는 객체를 만날 때까지 계속해서 요청을 전달하게 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Chain Of Responsibility
//
/////////////////////////////////////////////////////////////////////////////

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

#include <memory>

#include <iostream>
#include <deque>
#include <list>
#include <vector>
#include <algorithm>
#include <iomanip>


/////////////////////////////////////////////////////////////////////////////
//
// Chain Of Responsibility
//
//
/////////////////////////////////////////////////////////////////////////////
class Handler
{
public:
 typedef int Topic;

public:
 explicit Handler (Handler *s=0, Topic t=0) :
  Successor_(s),
  Topic_    (t)
 {
 }

 virtual ~Handler ()
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Successor_)
  {
   Successor_->HandleRequest ();
  }
  else
  {
   std::cout << "Handler::HandleRequest() : no Successor_" << std::endl;
  }
 }

 virtual void SetHandler (Handler *s=0, Topic t=0)
 {
  Successor_=s;
  Topic_    =t;
 }

protected:
 Handler* Successor_;
 Topic    Topic_;
};

class ConcreteHandler1 : public Handler
{
public:
 ConcreteHandler1 (Handler *s=0, Topic t=0) :
  Handler(s,t)
 {
 }
public:
 virtual void HandleRequest(void)
 {
  if (Topic_==1)
  {
   std::cout << "ConcreteHandler1::HandleRequest()" << std::endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 };
};

class ConcreteHandler2 : public Handler
{
public:
 ConcreteHandler2 (Handler *s=0, Topic t=0) :
  Handler(s,t)
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Topic_==2)
  {
   std::cout << "ConcreteHandler2::HandleRequest()" << std::endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 };
};

class ConcreteChildHandler : public ConcreteHandler2
{
public:
 ConcreteChildHandler (Handler *s=0, Topic t=0) :
  ConcreteHandler2(s,t)
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Topic_==3)
  {
   std::cout << "ConcreteChildHandler::HandleRequest()" << std::endl;
  }
  else
  {
   ConcreteHandler2::HandleRequest();
  }
 };
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Handler* handler1 = new Handler              ();
 Handler* handler2 = new ConcreteHandler1     (handler1, 1);
 Handler* handler3 = new ConcreteHandler2     (handler2, 1);
 Handler* handler4 = new ConcreteChildHandler (handler3, 2);
 Handler* handler5 = new ConcreteChildHandler (handler3, 3);

 handler1->HandleRequest();
 handler2->HandleRequest();
 handler3->HandleRequest();
 handler4->HandleRequest();
 handler5->HandleRequest();

 delete handler1;
 delete handler2;
 delete handler3;
 delete handler4;
 delete handler5;

 return 0;
}
-----------------------------------------------------------------------------Handler::HandleRequest() : no Successor_
ConcreteHandler1::HandleRequest()
ConcreteHandler1::HandleRequest()
ConcreteHandler2::HandleRequest()
ConcreteChildHandler::HandleRequest()

Posted by 셈말짓기 :

행위패턴-Command

2008. 8. 15. 01:31 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Command]
의도:
요청 자체를 객체화하는 것이다. 그리고 서로 다른 요청을 객체화하여 클라이언트에게
파라미터로 넘겨줄 수 있게한다.

다른이름:
Action, Transaction
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Command
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <deque>
#include <list>
#include <vector>
#include <algorithm>
#include <iomanip>


/////////////////////////////////////////////////////////////////////////////
//
// Command
//
//
/////////////////////////////////////////////////////////////////////////////
class Command
{
protected:
 Command () {}
public:
 virtual ~Command () {}

public:
 virtual void Execute   (void) = 0;
 virtual void Unexecute (void) {}
};


/////////////////////////////////////////////////////////////////////////////
//
// Utility
//
/////////////////////////////////////////////////////////////////////////////
template<class T>
struct deleteobject_functor : public std::unary_function<T, void>
{
public:
 void operator()(T ptr)
 {
  delete ptr;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
//
/////////////////////////////////////////////////////////////////////////////
class Receiver
{
public:
 void Print_A (int a)
 {
  std::cout << "Receiver::Print_A(" << a << ")" << std::endl;
 }
 void Print_B (const char *b)
 {
  std::cout << "Receiver::Print_B(" << b << ")" << std::endl;
 }
 void Print_C (void)
 {
  std::cout << "Receiver::Print_C()" << std::endl;
 }
 void Print_D (void)
 {
  std::cout << "Receiver::Print_D()" << std::endl;
 }
};

////-------------------------------------------------------------------------
////  Commands
////-------------------------------------------------------------------------
template <typename Receiver>
class SimpleCommand : public Command
{
public:
 typedef void (Receiver::*Action)(void);

public:
 SimpleCommand (Receiver *receiver, Action action) :
  Receiver_ (receiver),
  Action_   (action)
 {
 }

public:
 virtual void Execute (void)
 {  
  (Receiver_->*Action_) ();
 }

private:
 Receiver *Receiver_;
 Action    Action_;
};

class ConcreteACommand : public Command
{
public:
 ConcreteACommand (Receiver *receiver, int param) :
  Receiver_ (receiver),
  Param_    (param)
 {
 }

public:
 virtual void Execute (void)
 {  
  Receiver_->Print_A (Param_);
 }

private:
 Receiver *Receiver_;
 int       Param_;
};

class ConcreteBCommand : public Command
{
public:
 ConcreteBCommand (Receiver *receiver, std::string param) :
  Receiver_ (receiver),
  Param_    (param)
 {
 }

public:
 virtual void Execute (void)
 {  
  Receiver_->Print_B (Param_.c_str());
 }

private:
 Receiver    *Receiver_;
 std::string  Param_;
};

class MacroCommand : public Command
{
public:
 virtual ~MacroCommand ()
 {
  std::for_each (Commands_.begin(), Commands_.end(), deleteobject_functor<Command*>());
 }

protected:
 static void ExecuteCommand (Command* cmd)
 {
  cmd->Execute();
 }

public:
 void Add (Command* cmd)
 {
  Commands_.push_back (cmd);
 }

 virtual void Execute (void)
 {
  std::for_each (Commands_.begin(), Commands_.end(), ExecuteCommand);
 }

private:
 std::list<Command*> Commands_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Receiver     receiver;
 MacroCommand macrocmd;
 
 macrocmd.Add (new ConcreteACommand (&receiver, 100));
 macrocmd.Add (new ConcreteBCommand (&receiver, "Hello World!"));
 macrocmd.Add (new SimpleCommand<Receiver> (&receiver, &Receiver::Print_C));
 macrocmd.Add (new SimpleCommand<Receiver> (&receiver, &Receiver::Print_D));

 macrocmd.Execute();

 return 0;
}
-----------------------------------------------------------------------------

Receiver::Print_A(100)
Receiver::Print_B(Hello World!)
Receiver::Print_C()
Receiver::Print_D()



 


Posted by 셈말짓기 :


# WinCE -> PC : 192.168.55.100를 이용하여 접속
  PC    = 192.168.55.100
  WinCE = 192.168.55.101

# PC -> WinCE : 127.0.0.1을 이용하여 접속
  1. ActiveSync Proxy 설정
     1) PC의 레지스트리
         HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts에
         DWORD값 설정후 적당한 이름을 붙인후 Port번호 기입

------------------------------------------------------------------------------------
 Test.Reg
------------------------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts]
"Test"=dword:000007d0
------------------------------------------------------------------------------------

원본:
http://leigh.innori.com/2

Posted by 셈말짓기 :

#if !defined (__REFCOUNTEDAUTOPTR__H__)
#define __REFCOUNTEDAUTOPTR__H__

#pragma once


// ------------------------------------------------------------------------- //
//  Global
// ------------------------------------------------------------------------- //
template<class T>              class CAutoBasicPtr;
template<class T, class lockT> class CRefcountedAutoPtrRep;
template<class T, class lockT> class CRefcountedAutoPtr;


// ------------------------------------------------------------------------- //
//  Class: CAutoBasicPtr
// ------------------------------------------------------------------------- //
template <class T>
class CAutoBasicPtr
{
public:
 explicit CAutoBasicPtr (T *p = NULL)
  : m_pPtr (p)
 {
 };
 
 CAutoBasicPtr (CAutoBasicPtr<T> &rhs)
  : m_pPtr (rhs.release ())
 {
 };
 
 CAutoBasicPtr<T> &operator= (CAutoBasicPtr<T> &rhs)
 {
  if (this != &rhs)
  {
   this->Reset (rhs.Release ());
  }
  return *this;
 };
 
 ~CAutoBasicPtr (void)
 {
  delete this->Get ();
 };

public:
 T &operator *() const
 {
  return *this->Get ();
 };
 
 T *Get (void) const
 {
  return this->m_pPtr;
 };
 
 T *Release (void)
 {
  T *old = this->m_pPtr;
  this->m_pPtr = NULL;
  return old;
 };
 
 void Reset (T *p = NULL)
 {
  if (this->Get () != p)
   delete this->Get ();
  this->m_pPtr = p;
 };
 
protected:
 T *m_pPtr;
};


// ------------------------------------------------------------------------- //
//  Class: CRefcountedAutoPtrRep
// ------------------------------------------------------------------------- //
template<class T, class lockT>
class CRefcountedAutoPtrRep
{
private:
 friend class CRefcountedAutoPtr <T, lockT>;

protected:
 mutable lockT m_Lock;
 CAutoBasicPtr<T> m_Ptr;
 LONG          m_nRefCount;
 
private:
 CRefcountedAutoPtrRep (T* p=NULL)
  : m_Ptr(p), m_nRefCount(0)
 {
 };

 ~CRefcountedAutoPtrRep ()
 {
 };

private:
 static CRefcountedAutoPtrRep<T,lockT>* Create (T *p);
 static CRefcountedAutoPtrRep<T,lockT>* Attach (CRefcountedAutoPtrRep<T,lockT> *&rep);
 static void Detach (CRefcountedAutoPtrRep<T,lockT> *&rep);
 static void Assign (CRefcountedAutoPtrRep<T,lockT> *&rep, CRefcountedAutoPtrRep<T,lockT> *new_rep);
};

template<class T, class lockT>
CRefcountedAutoPtrRep<T,lockT>* CRefcountedAutoPtrRep<T,lockT>::Create (T *p)
{
 CRefcountedAutoPtrRep<T,lockT> *ret = NULL;

 ret = new CRefcountedAutoPtrRep<T,lockT> (p);

 return ret;
}

template<class T, class lockT>
CRefcountedAutoPtrRep<T,lockT>* CRefcountedAutoPtrRep<T,lockT>::Attach (CRefcountedAutoPtrRep<T,lockT> *&rep)
{
 CXASSERT (rep!=NULL);
 
 CSyncGuard<lockT> g(rep->m_Lock);

 rep->m_nRefCount++;

 return rep;
}

template<class T, class lockT>
void CRefcountedAutoPtrRep<T,lockT>::Detach (CRefcountedAutoPtrRep<T,lockT> *&rep)
{
 CXASSERT (rep!=NULL);

 CRefcountedAutoPtrRep<T,lockT> *del = NULL;

 {
  CSyncGuard<lockT> g(rep->m_Lock);

  if (rep->m_nRefCount-- == 0)
   del = rep;
 }
 if (del)
  delete del;
}

template<class T, class lockT>
void CRefcountedAutoPtrRep<T,lockT>::Assign (CRefcountedAutoPtrRep<T,lockT> *&rep, CRefcountedAutoPtrRep<T,lockT> *new_rep)
{
 CXASSERT (rep!=NULL);
 CXASSERT (new_rep!=NULL);

 CRefcountedAutoPtrRep<T,lockT> *del = 0;

 {
  CSyncGuard<lockT> g(rep->m_Lock);

  del = rep;
  rep = new_rep;

  if (del->m_nRefCount-- > 0)
   return;
 }

 delete del;
}


// ------------------------------------------------------------------------- //
//  Class: CRefcountedAutoPtr
// ------------------------------------------------------------------------- //
template<class T, class lockT=CNullSync>
class CRefcountedAutoPtr
{
private:
 friend class CRefcountedAutoPtrRep <T, lockT>;

private:
 CRefcountedAutoPtrRep<T,lockT>* m_pRep;

public:
 CRefcountedAutoPtr (T* p=0)
  : m_pRep(CRefcountedAutoPtrRep<T,lockT>::Create (p))
 {
 };

 CRefcountedAutoPtr (const CRefcountedAutoPtr<T,lockT> &copy)
  : m_pRep( CRefcountedAutoPtrRep<T,lockT>::Attach ( ( (CRefcountedAutoPtr<T, lockT> &)copy) .m_pRep ) )
 {
 };

 virtual ~CRefcountedAutoPtr()
 {
  CRefcountedAutoPtrRep<T,lockT>::Detach (m_pRep);
 };

public:
 inline void operator=(const CRefcountedAutoPtr<T,lockT>& copy)
 {
  CRefcountedAutoPtr<T,lockT> &r = (CRefcountedAutoPtr<T,lockT> &)copy;

  CRefcountedAutoPtrRep<T,lockT>::Assign (m_pRep, CRefcountedAutoPtrRep<T,lockT>::Attach (r.m_pRep));
 };

 inline bool operator==(const CRefcountedAutoPtr<T,lockT>& crep) const
 {
  return (m_pRep == crep.m_pRep);
 };

 inline bool operator!=(const CRefcountedAutoPtr<T,lockT>& crep) const
 {
  return (m_pRep != crep.m_pRep);
 };
 
 inline T* operator->() const
 {
  return m_pRep->m_Ptr.Get();
 };

 inline T* Get(void) const
 {
  return m_pRep->m_Ptr.Get();
 };

 inline LONG Count(void) const
 {
  return m_pRep->m_nRefCount;
 };
};

#endif // !defined(__REFCOUNTEDAUTOPTR__H__)

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
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 셈말짓기 :

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

#include <typeinfo.h> // Compile Option: /GR
#include <iostream>

using namespace std;

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

class SpaceShip: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
};

class SpaceStation: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
};


class Asteroid: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
};

GameObject::~GameObject()
{
}

void SpaceShip::Collide(GameObject& otherObject)
{
 const type_info& objectType = typeid(otherObject);

 if(objectType == typeid(SpaceShip) )
 {
  cout << "The space ship is colliding with a space ship";
  cout << endl;
 }
 else if (objectType == typeid(SpaceStation) )
 {
  cout << "The space ship is colliding with a space station";
  cout << endl;  
 }
 else if (objectType == typeid(Asteroid) )
 {
  cout << "The space ship is colliding with a asteroid";
  cout << endl;  
 }
 else
 {
  cout << "The space ship is colliding with a unknown object";
  cout << endl;
  cout << " Shall we throw a unknown object type exception";
  cout << endl;
 }
}

void SpaceStation::Collide(GameObject& otherObject)
{
 const type_info& objectType = typeid(otherObject);

 if(objectType == typeid(SpaceShip) )
 {
  cout << "The space station is colliding with a space ship";
  cout << endl;
 }
 else if (objectType == typeid(SpaceStation))
 {
  cout << "The space station is colliding with a space station";
  cout << endl;  
 }
 else if (objectType == typeid(Asteroid))
 {
  cout << "The space station is colliding with a asteroid";
  cout << endl;  
 }
 else
 {
  cout << "The space station is colliding with a unknown object";
  cout << endl;
  cout << " Shall we throw a unknown object type exception";
  cout << endl;
 }
}

void Asteroid::Collide(GameObject& otherObject)
{
 const type_info& objectType = typeid(otherObject);

 if(objectType == typeid(SpaceShip) )
 {
  cout << "The asteroid is colliding with a space ship";
  cout << endl;
 }
 else if (objectType == typeid(SpaceStation))
 {
  cout << "The asteroid is colliding with a space station";
  cout << endl;  
 }
 else if (objectType == typeid(Asteroid))
 {
  cout << "The asteroid is colliding with a asteroid";
  cout << endl;  
 }
 else
 {
  cout << "The asteroid is colliding with a unknown object";
  cout << endl;
  cout << " Shall we throw a unknown object type exception";
  cout << endl;
 }
}

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

 GameObject *p=&ship;

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

 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 space ship

Posted by 셈말짓기 :

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

#include <typeinfo>
#include <iostream>

using namespace std;

class SpaceShip;
class SpaceStation;
class Asteriod;

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

public:
 virtual void Collide(SpaceShip& otherObject) = 0;
 virtual void Collide(SpaceStation& otherObject) = 0;
 virtual void Collide(Asteriod& otherObject) = 0;

 virtual ~GameObject();
};

class SpaceShip: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
public:
 virtual void Collide(SpaceShip& otherObject);
 virtual void Collide(SpaceStation& otherObject);
 virtual void Collide(Asteriod& otherObject);
};

class SpaceStation: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
public:
 virtual void Collide(SpaceShip& otherObject);
 virtual void Collide(SpaceStation& otherObject);
 virtual void Collide(Asteriod& otherObject);
};


class Asteriod: public GameObject
{
public:
 virtual void Collide(GameObject& otherObject);
public:
 virtual void Collide(SpaceShip& otherObject);
 virtual void Collide(SpaceStation& otherObject);
 virtual void Collide(Asteriod& otherObject);
};

GameObject::~GameObject()
{
}

void SpaceShip::Collide(GameObject& otherObject)
{
 otherObject.Collide(*this);
}

void SpaceShip::Collide(SpaceShip& otherObject)
{
 cout << "The space ship is colliding with a space ship";
 cout << endl;
}

void SpaceShip::Collide(SpaceStation& otherObject)
{
 cout << "The space ship is colliding with a space station";
 cout << endl;
}

void SpaceShip::Collide(Asteriod& otherObject)
{
 cout << "The space ship is colliding with a asteriod";
 cout << endl;
}

void SpaceStation::Collide(GameObject& otherObject)
{
 otherObject.Collide(*this);
}

void SpaceStation::Collide(SpaceShip& otherObject)
{
 cout << "The space station is colliding with a space ship";
 cout << endl;
}

void SpaceStation::Collide(SpaceStation& otherObject)
{
 cout << "The space station is colliding with a space station";
 cout << endl;
}

void SpaceStation::Collide(Asteriod& otherObject)
{
 cout << "The space station is colliding with a asteriod";
 cout << endl;
}

void Asteriod::Collide(GameObject& otherObject)
{
 otherObject.Collide(*this);
}

void Asteriod::Collide(SpaceShip& otherObject)
{
 cout << "The space ship is colliding with a space ship";
 cout << endl;
}

void Asteriod::Collide(SpaceStation& otherObject)
{
 cout << "The space ship is colliding with a space station";
 cout << endl;
}

void Asteriod::Collide(Asteriod& otherObject)
{
 cout << "The space ship is colliding with a asteriod";
 cout << endl;
}

int _tmain (int argc, _TCHAR* argv[])
{
 GameObject  *p1;
 GameObject  *p2;

 SpaceShip    ship;
 SpaceStation station;
 Asteriod     asteriod;

 p1 = &ship;
 p2 = &ship;     p1->Collide(*p2);
 p2 = &station;  p1->Collide(*p2);
 p2 = &asteriod; p1->Collide(*p2);

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

Posted by 셈말짓기 :

//////////////////////////////////////////////////////////////////////////////////////
//
// 템플릿 클래스 메소드 특화
//
//
//////////////////////////////////////////////////////////////////////////////////////
#include <string>

#include <windows.h>

template <class CharType>
class Message
{
public:
 void Print (void);
 void Set   (std::basic_string < CharType > s);

public:
 std::basic_string < CharType > text_;
};

template <class CharType>
void Message<CharType>::Set (std::basic_string < CharType > s)
{
 text_ = s;
}

template <class CharType>
void Message<CharType>::Print (void)
{
 OutputDebugStringW (text_.c_str());
}

template <>
void Message<char>::Print (void)
{
 printf (text_.c_str());
}

int _tmain(int argc, _TCHAR* argv[])
{
 Message<wchar_t> b;

 b.Set (L"bbb\r\n");
 b.Print();


 Message<char> a;

 a.Set ("aaa\r\n");
 a.Print();


 return 0;
}
--------------------------------------------------------------------------------------
aaa (콘솔창)
--------------------------------------------------------------------------------------
bbb (디버깅창)





//////////////////////////////////////////////////////////////////////////////////////
//
// 템플릿 클래스 특화 (Specialization of template class)
//
//
//////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>
#include <iostream>

template<class T>
class Min
{
public:
 const T& Is (const T &a, const T &b)
 {
  std::cout << "template<class T> class Min::Is ("
      << static_cast<int>(a) << ", "
      << static_cast<int>(b) << ")"
      << std::endl;

  return (a<b) ? a: b;
 }
};

template<>
class Min <char>
{
public:
 const char& Is (const char &a, const char &b)
 {
  std::cout << "template<> class Min<char>::Is ( \'"
      << a << "\', "
      << b << "\' )"
      << std::endl;

  return (a<b) ? a: b;
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 Min<int>  a;
 //Min<>     b; <- error
 Min<char> c;
 //Min<>     d; <- error

 a.Is (1,2);
 //b.Is (3,4);
 c.Is ('a','b');
 //d.Is ('c','d');

 return 0;
}
--------------------------------------------------------------------------------------
template<class T> class Min::Is (1, 2)
template<> class Min<char>::Is ( 'a', b' )





//////////////////////////////////////////////////////////////////////////////////////
//
// 함수 템플릿 특화 (Specialization of function template)
//
//
//////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>
#include <iostream>

template<class T>
const T& Min (const T &a, const T &b)
{
 std::cout << "template<class T> const T& Min ("
           << static_cast<int>(a) << ", "
     << static_cast<int>(b) << ")"
     << std::endl;

 return (a<b) ? a: b;
}

template<>
const char& Min <char> (const char &a, const char &b)
{
 std::cout << "template<> const char& Min <char> ( \'"
           << a << "\', "
     << b << "\' )"
     << std::endl;

 return (a<b) ? a: b;
}

int _tmain(int argc, _TCHAR* argv[])
{
 Min<int>  ( 1 ,  2 );
 Min<>     ( 3 ,  4 );
 Min<char> ('c', 'd');
 Min<>     ('a', 'b');

 return 0;
}
--------------------------------------------------------------------------------------
template<class T> const T& Min (1, 2)
template<class T> const T& Min (3, 4)
template<> const char& Min <char> ( 'c', d' )
template<> const char& Min <char> ( 'a', b' )

//
// cf>
//   함수 템플릿은 아래와 같이 정의 할 수 있지만
//   template <class T, int X>
//   void foo_func (T a)
//   {
//   }
//   아래와 같이 기본 템플릿 인수는 정의 할 수 없다.
//   template <class T, int X=0>
//   void foo_func (T a)
//   {
//   }
//   기본 템플릿 인수는 클래스 탬플릿에서만 사용이 가능하다.
//
//   또한, 부분특화 템플릿 함수는 사용 될 수 없다.
//





//////////////////////////////////////////////////////////////////////////////////////
//
// 템플릿 클래스 부분특화 (Partial specialization of template class)
//
//
//////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>
#include <iostream>

// partial specialization

class partial_specialization
{
public:
 partial_specialization ()
 {
  std::cout << "partial_specialization ()" << std::endl;
 }
 ~partial_specialization ()
 {
  std::cout << "~partial_specialization ()" << std::endl;
 }
};

template <class T1, class T2> class foo
{
public:
 foo ()
 {
  std::cout << "foo ()" << std::endl;
 }

 ~foo ()
 {
  std::cout << "~foo ()" << std::endl;
 }
};

template <class T1> class foo <T1, partial_specialization>
{
public:
 foo ()
 {
  std::cout << "foo() 2" << std::endl;
 }

 ~foo ()
 {
  std::cout << "~foo() 2" << std::endl;
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 foo<int, int>                    a;
 foo<int, partial_specialization> b;

 return 0;
}
--------------------------------------------------------------------------------------
foo ()
foo() 2
~foo() 2
~foo ()

Posted by 셈말짓기 :