instance()라는 메소드를 통해서 해당 클래스의 대표 객체를 반환하는 기법을 이용하는 다른 설명을 해 보겠습니다. 이번에는 Log라는 클래스를 예를 들어 보겠습니다.


class Log
{
protected:
  FILE* FP;
  // ...
public:
  void __cdecl trace(const char* fmt, ...);
};


위 Log라는 클래스는 프로그램을 실행하면서 로그를 남기고 싶을 경우 특정 파일로 해당 메세지를 출력해 주는 클래스입니다. 당연히 파일을 access할 수 있는 file pointer가 멤버 변수로 들어가 있습니다.




하나의 프로젝트에 10명의 프로그래머가 투입되었다고 가정합시다. 모든 프로그래머는 Log 클래스를 이용해서 로그를 남기고 싶어 합니다. 당연히 모든 프로그래머는 Log 클래스의 객체를 얻어 와야 하죠. 그런데 10명의 모든 프로그래머들이 Log 클래스를 각각 따로 생성해서 사용을 한다면 file pointer가 10개가 생성되는 낭비를 초래할 수 있습니다. 그래서 이러한 경우 Log 클래스도 instance()라는 메소드를 통해서 대표적인 전역 객체 하나를 반환해 주는 메소드를 제공하는 것이 좋습니다.


class Log
{
  // ...
public:
  static Log& instance();
};




같은 프로젝트를 하고 있는 새로운 프로그래머 한명은 다른 파일에 로그를 남기고 싶다는 가정을 할 수가 있습니다. 당연히 instance()가 반환하는 공통 객체를 사용하지 않고 별도로 Log 객체를 만들어 사용해야 하겠죠. 이런 경우에는 Log 클래스의 constructor  및 destructor는 public으로 선언을 해 줘서 외부에서 객체의 생성이 가능하도록 만들어야 합니다. 결론적으로 Log 클래스는 다음과 같이 선언할 수 있습니다.


class Log
{
public:
  Log();
  virtual ~Log();
protected:
  FILE* FP;
  // ...
public:
  void __cdecl trace(const char* fmt, ...);
public:
  static Log& instance();
};




여러 객체가 생성이 될 수 있다는 점을 감안하면 Log 클래스는 분명 singleton pattern은 아닙니다. 하지만 instance()라는 메소드를 통해서 대표적인 전역 객체를 반환해 주는 기능이 singleton pattern과 비슷하므로 첨언하여 설명을 해 보았습니다.