얼마나 private이 비공개적인가? 라는 질문을 보고, 어떤 관점에서 비공개적인지 궁금해 했다. 컴파일 타임의 비공개적인가를 뜻하는건지, 런타임의 비공개적인가를 뜻하는지에 대해서 생각을 했었다.
책에선 이 두가지를 통틀어 그 원리에 대해서 설명 하고 있는데, 다음 질문을 통해서, 알아 보도록 하자.
1 ) Twice 함수들이 링크 과정에 포함되는 다른 어떤 번역 단위에 정의되어 있다고 할 때, 다음의 C++ 프로그램이 제대로 컴파일, 실행 될까? 아니라면 왜 그럴까? 된다면, 무엇이 출력 될까?
예제 코드
.. 제대로 컴파일도 안되니, 실행도 안된다. 어떻게 컴파일이 되지 않을까?
제일 우선적인게 바로 std::complex<float> 이 보이지 않기 때문인데, #include <complex> 를 하면 이 부분은 해결 된다.
했는데도 컴파일이 되지 않는다. 이번엔 어떻게 컴파일이 되지 않을까?
바로 Calc의 private 멤버, Twice(int) 에 접근 할 수 없기 때문이다.
Twice(double)으로 어떻게 호출 되지 않는가?
절대 그러지 못한다. 왜냐하면 C++ 에서 함수를 호출 하라면, 먼저 알맞는 함수를 찾고, 접근하여 호출 하기 때문이다. 함수를 호출은 가시성(visibility)개념과, 접근하는 것은 접근성(accessibility)개념, 그리고 중복 적재 해소개념을 사용 하는데, 가시성이 먼저이고 중복 적재 해소개념을 사용 한 뒤에 접근성을 사용한다.
1. 가시성(visibillity) 개념 사용
가시성은 koening lookup 을 사용 하는데, c.Twice( 21 ); 을 해석 할 때, Calc 클래스에서 처음 찾아 보다가, Twice를 찾게 되고, 3개의 함수를 찾고, 더 이상 확장 검색을 하지 않은다. 이는 찾고자 하는 동등한 이름구역들 안에서만 제일 먼저 찾는데, 찾았다면, 확장해서 더 찾으려고 하지 않는 규칙이 있다고 보면 된다.
2. 중복 적재 해소 개념 사용
Calc 에서 3개의 Twice 함수를 찾았으면, 이제 인자로 3개의 함수 중 가장 적절한 함수를 찾는다. 위에선 당연히 Twice(int) 이다.
3. 접근성(accessibility) 개념 사용
이제 Twice(int) 를 호출 해도 되는 접근성을 검사 하는데, 여기서 에러!! 왜냐하면, private 영역이기 때문이다.
다른 예를 들어 한가지 테스트를 더 해보자.
여기서 위의 3가지 개념들을 통해서 설명하면
1. 가시성(visibility) 개념 사용
역시 3개의 Twice() 함수를 발견하고
2. 중복 적재 해소 개념 사용
여기서 Twice(double) 과 Twice(unsigned int) 중 둘다 형변환을 거쳐야 하는것 이기에, 무엇을 호출해야 할지 모호해 져서 실패하게 된다.
다른 예를 또 들어 보자.
여기도 또한 3가지 개념을 사용해서 생각해 보면,
1. 가시성(visibility) 개념 사용
제일 먼저.. std::string Twice( std::string ) 찾았고, 검색을 중지한 뒤에 21을 std::string 으로 바꾸려 했을 때, 형변환 에러가 이러나게 되어, 컴파일 타임 에러를 벹어 낸다.
그렇다면, 이것들은 무엇을 나타내어 주기 위한 것인가?
이것들은 private 이나 public, protected, 즉 접근 지시자(access specifier)는 가시성의 대상이 될 뿐, 가시성을 관여하지 않는 다는 것이다. 이 말은, private 함수를 public 함수로 바꾼다 하더라도, 가시성에는 변화가 없다는 것을 뜻한다.
이것은 프로그래머에 의해서, 접근 지시자(access specifier)를 바꾼다 하더라도, 가시성이 변경되지 않기 때문에, 보다 견고한 프로그래밍이 가능해 지는 효과를 갖게 해준다.
마지막 질문! private 지시자는 얼마나 비공개적 인가?
이것은 접근성에 대해서만, 비공개적 이다! 라고 말 할 수 있을 것이다!
이 질문의 답은, C++ 03의 제11항의 내용과 같이 보면 더욱 이해하기 쉽다.
private 멤버 : 이런 멤버의 이름은 멤버가 선언된 클래스의 멤버들과 친구들만 접근할 수 있다.
protected 멤버 : private 의 사용 권한 + 클래스에서 파생된 클래스의 멤버들과 친구들이 접근할 수 있다.
public 멤버 : 이런 멤버의 이름은 어디서나 접근할 수 있다.
이상으로 이번 항목을 읽어 보았다.
총평
나는 정말 많은 부분을 지나치며, 책을 읽었다고 느꼈다. 물론 이런 내용이 있다고 책에 나오는것을 이번이 처음 보는 것이지만, 다른 것들을 통해서 충분히 유추해 볼 수 있는 내용임에도, 알지 못한것은 분명 내 잘못이다.
신기한것은 공부를 할 때, 이런 질문을 어떻게 하게 되는가? 에 있다. 허브셔터는 이런 질문이 나오기 까지 얼마나, 고심하고 했을까?
이 부분 때문에, 요즘 드는 생각은, "프로그래머는 프로그래밍만 해서는 안된다." 이다. 이 생각은 프로그래밍은 표현의 수단일 뿐, "무엇을 표현 할 것인가?" 를 결정해야 하는 단계까지 나 자신을 끌어 올릴 필요가 있다는 생각이다.
예전에 읽었던 글 중에, "왜?" 라는 질문을 "어떻게?"로 바꾸는것이 더 좋다. 라는 글을 읽고 감동 받은 적이 있었다. 지금 순간, "어떻게" 라는 질문을 해야만 한다고 느낀다.
'책 정리 > Exceptional C++ Style' 카테고리의 다른 글
항목 21 : 컨테이너의 메모리 사용, 2부 : 얼마나 큰가? ( 난이도 : 3 ) (0) | 2009.01.22 |
---|---|
항목 20 : 컨테이너의 메모리 사용, 1부 : 메모리 관리의 여러 수준 ( 난이도 : 3 ) (0) | 2009.01.22 |
항목 19 : 파생된 클래스들에 대한 규칙 강제 ( 난이도 : 5 ) (0) | 2009.01.19 |
항목 18 : 가상성 ( 난이도 : 7 ) (2) | 2009.01.17 |
항목 17 : 캡슐화 ( 난이도 : 4 ) (0) | 2009.01.16 |
항목 15 : 접근 권한의 사용과 오용 ( 난이도 : 6 ) (1) | 2009.01.15 |
항목 14 : 순서의 중요성 ( 난이도 : 2 ) (1) | 2009.01.14 |
항목 13 : 예외 명세에 대한 실용적인 고찰 ( 난이도 : 6 ) (1) | 2009.01.14 |
항목 12 : 예외 안전성 : 추구할 가치가 있는가? ( 난이도 : 7 ) (1) | 2009.01.13 |
항목 11 : try 와 catch ( 난이도 : 3 ) (1) | 2009.01.13 |
최근댓글