2009. 7. 15. 23:31

싱글톤 구현시 함수 정적객체 이용의 이점

싱글톤이란 클래스의 유일한 인스턴스만 생성하게 하는 "의도"를 가진 디자인 패턴이다. 보통은 그냥  아래와 같이 클래스의 정적 객체로 구현하여 사용하였다.

(생성자를 private 으로 하여 외부에서 객체 생성을 막는것에 주의)

class Printer{

private:

        Printer(){

               cout << "created printer \n";

        }

        Printer(const Printer & printer);

        static Printer printer;

public:

        static Printer & thePrinter() {

               return printer;

        }

};


Printer Printer::printer;


이렇게 구현하여 사용함에 있어 별 문제를 못느꼈으나, 다음과 같은 상황일때 고민을 했던적이 있다.

static 정적 객체가 여러개이고, 각 정적 객체가 연관성을 가지게 되어 객체의 초기화 순서가 중요하게 될 경우 골치가 아프게 된다. 예로 A, B 객체가 모두 클래스 정적 객체인데 B는 A이후에 생성되어야 한다면 이때는 클래스 정적 객체로는 해결하기 어렵다.

다시 Printer 클래스를 아래처럼 구현해 보자.

class Printer{

private:

        Printer(){

               cout << "created printer \n";

        }

        Printer(const Printer & printer);

 

        friend Printer & thePrinter();

};

 

Printer & thePrinter()

{

        static Printer printer;

        return printer;

}



friend 함수를 이용하여 클래스 정적 객체가 아닌 함수 정적 객체를 이용하였다. 이렇게 구현하면 thePrinter() 라는 함수가 호출되기 전까지는 함수 정적 객체는 생성되지 않는다. 따라서,

1. 함수가 호출되지 않으면 객체가 생성되지 않는다.
2. 함수 호출 순서를 조정함으로써 객체의 초기화 순서를 조정할 수 있다.

는 장점을 얻을 수 있다.

주의할 점은 thePrinter 를 inline 으로 선언하면 안된다는 것이다. inline 으로 선언되면 한 프로그램안에서 중복될 수 있다. 따라서 중복된 함수 코드마다 정적 객체가 들어가게 되므로 정적 객체를 선언한 비멤버 함수는 절대로 inline 으로 선언하면 안 된다.

참고 : More Effective C++