이번에는 singleton 클래스를 상속하는 것에 대해서 얘기를 해 보겠습니다. 얘기를 시작하기 이전에 곰곰히 생각해 볼 문제가 있습니다.




"과연 singleton 객체의 상속은 타당한가?"




예를 들어 보겠습니다. App라는 클래스가 있고 이는 singleton pattern이며 instance()라는 메소드로 객체에 접근을 할 수가 있다고 가정을 합니다. 이 상태에서 프로그래머는 MyApp라는 클래스를 App에서 상속을 받고 싶어 합니다.


class App
{
public:
  static App& instance();
};

class MyApp : public App
{
};




잘 생각해 보면 문제가 복잡해 집니다. App::instance()라는 메소드를 활용하면 App 클래스 객체가 반환되지 MyApp 클래스 객체를 반환되어 지지가 않습니다. 따라서 MyApp 클래스에서도 똑같이 별도의 메소드를 제공해야 한다는 결론에 도달할 수 있습니다.


class MyClass : public App
{
public:
  static MyApp& instance();
};




이렇게 되면 의아한 결과를 낳을 수 있습니다. 왜냐 하면 어플리케이션 코드에서 App::instance() 와 MyApp::instance()를 호출하게 되면 App 객체 하나, MyApp 객체 하나 해서 2개의 instance가 생기게 됩니다. 결국 "single 클래스의 객체는 하나뿐이다" 라는 원래의 취지를 위반하게 되죠.


1. singleton 클래스를 상속을 받게 되면 하위 클래스에서도 부모 클래스와 마찬가지로 인터페이스에 접근할 수 있는 메소드를 별도로 또 제공해야 한다.


2. singleton 클래스는 상속을 받게 되면 클래스 갯수만큼 instance가 여러개 생성될 수 있다.


3. 그러므로 singleton 클래스는 애시당초 상속이 되지 않도록 하는 것이 좋다.




C++에서 클래스 상속을 원하지 않는 경우라고 한다면 클래스(App)의 모든 constructor 혹은 destructor를 private으로 선언을 하여 상속을 방지할 수가 있습니다(상속을 방지하기 위해서 java에서는 final이라는 keyword가 제공되는데, C++에서 이와 비슷하게 해 보려고 이렇게 저렇게 template를 만들어 구현을 해 보려고 하였지만 올바른 방법을 도출할 수가 없더군요).




참고로 클래스의 모든 멤버 객체들을 전부 static으로 선언해 버리는 Monostate Pattern 이라는 것도 있으니 참고하시기 바랍니다. 이 경우 class라는 예약어보다는 차라리 namespace라는 예약어를 사용하는 것이 더 직관적일 것입니다.