gimmesilver's blog

Agbird.egloos.com

포토로그



지난 번에 낸 퀴즈 답 기타등등

먼저 어렵게 문제 풀기 글에서 낸 '납골당 살인 사건' 문제의 답은 '살해당한 남자는 루즈벨트에게 투표하지 않았다.' 입니다. 그 이유를 설명하기 위해 원래 글을 다시 인용해보면...

<전략>...편지에는 오늘 밤 자정에 공동 묘지에 있는 납골당으로 나오라는 내용이 적혀 있었다. 그 남자는 누군가의 장난이라 생각했지만 호기심에 편지의 내용대로 납골당에 가보기로 결정했다. 자정 무렵 그가 납골당에 도착했을 때 거기에는 아무도 없었고 단지 초승달만이 희미한 빛을 비추며 그를 반기고 있을 뿐이었다....  <후략>

 여기서 강조한 부분에 보면 초승달이 자정에 떠있다고 나와 있는데 초승달은 자정에 뜨지 않습니다. 초등학교 시절 자연 수업의 내용을 어렴풋이 떠올려보면 달은 지구를 중심으로 약 30일을 주기로 시계 반대 방향으로 도는데 초승달은 달이 태양을 막 지났을 때 지구에서 보이는 모습입니다. 따라서 저녁 무렵 해가 막 지기 시작하는 서쪽하늘에 잠시 떴다가 집니다(자정 무렵에 볼 수 있는 건 보름달 정도죠). 다만 한가지 예외가 되는 곳이 있는데 자정 무렵에도 해를 볼 수 있는 극지방이 바로 그렇습니다.
 따라서 살해당한 남자는 극 지방 근처에 사는 사람이라는 추론이 가능합니다. 극지방이면서 미국 대통령 선거를 할 수 있는 곳으로 알래스카가 있습니다. 하지만 알래스카 주민이 미국 대통령 선거 투표를 할 수 있었던 것은 1960년 부터였습니다. 따라서 살해당한 남자는 1904년에 있었던 미국 대통령 선거에서 루즈벨트에게 투표할 수 없었습니다.

 참고로 저는 이 남자가 스웨덴이나 노르웨이 쯤에 사는 사람이기 때문에 미국 대통령 선거에 투표할 수 없었을 것이라고 생각했습니다. 알래스카에 대해서는 미처 생각하지 못했었는데 알래스카가 언제 미국에 편입 되었고 투표권이 생겼는지는 몰랐기 때문에 만약 추론과정에서 알래스카를 떠올렸더라면 아마 더 헷갈려서 문제를 못 풀었을 거라 생각합니다. 기거렌처가 말하는 '유익할 정도의 무지' 에 해당하겠죠...(언젠가 이에 관한 글을 한번 써볼 생각입니다)

 C++에서 싱글톤 구현하기 글에서 낸 '상속이 불가능한 클래스 만들기' 는 가장 쉽게 떠올릴 수 있는 게 생성자를 private 으로 만들고 대신 펙토리 메소드를 제공하는 것입니다. 아마 많은 분들이 이 방법을 떠올리셨을 거라 생각합니다.

class Test {
  private:
    Test() {}
  public:
    static Test* getInstance() {
      return new Test();
    }  
};

 하지만 이 경우 객체 관리가 번거롭고 특히 임시 객체를 만들 수 없다는 점에서 썩 만족스런 방법이 아닙니다. 따라서 임시 객체나 전역 객체를 생성할 수 있으려면 생성자를 private 권한으로 만들지 않고도 상속이 불가능하게 만들어야 합니다. 이를 위한 방법은 아래와 같습니다.

class Test
class InheritanceLock {
  friend class Test;
  private:
    InheritanceLock() {}
    InheritanceLock(const InheritanceLock& other) {}
};

class Test : public virtual InheritanceLock {
  // ...
};

 private 생성자를 가진 클래스를 상속받을 수 있는 방법은 상속 대상 클래스(위 코드의 Test)를 부모 클래스가 friend 로 선언하는 것입니다. 하지만 friend 는 상속 대상이 아니기 때문에 Test 클래스를 상속하는 다른 클래스들은 Test의 부모 클래스인 InheritanceLock 클래스의 생성자를 호출할 수 없습니다. 따라서 만약 Test 를 상속받은 클래스의 객체를 생성하려고 하면 컴파일 에러가 발생합니다.
 이 방법 역시 이전 글에서 소개한 피닉스 싱글톤처럼 상당히 tricky 한 방법입니다(게다가 부모가 자식이랑 친구먹자고 하는 이런 콩가루 클래스 구조는 사회적으로도 용납할 수 없습니다). 그냥 이런 방법이 있구나 정도로만 알고 넘어가면 되겠습니다. 
 
p.s. 위 두 문제를 모두 맞추신 irtiger 님께는 상품으로 힘찬 박수를 보내드립니다. 짝!짝!짝!
p.p.s. C++에서 싱글톤 구현하기 댓글로 김형섭 님이 내신 '반드시 상속하게 만드는 방법' 문제의 답은 '순수 가상 클래스로 만든다.' 입니다.
p.p.s. 위 두 분이 가급적 싱글톤이나 static 사용을 지양하는 것이 좋다고 말씀하셨는데 좋은 말씀입니다. 다만 경험 상 C++ 객체 생명 주기와 관련해서 발생하는 버그는 굉장히 미묘하고 검출하기도 힘들기 때문에 이에 대해서는 확실히 이해하는 것이 중요하다고 생각합니다. 그래서 static 생성/소멸 시점을 정확히 아는 것이 중요하다고 언급했습니다.

덧글

댓글 입력 영역