2013년 11월 12일 화요일

[C++] C++의 난감한 상황...

C++의 private 접근제어 키워드에 대하여 이야기를 한 바 있다.
이번에는 어찌 보면 좀 황당한(?) 소스코드를 이야기하고자 한다.

참고로 지금 언급하고자 하는 개념은, 어떤 블로그에서는 당당하게 "C++ 클래스의 private 멤버 변수에 접근하고 값을 변경하는 방법!!" 이라고 소개되기도 하였다. (개인적으로 참 난감한 글이었다.)

아래 소스코드를 보자.

#include <iostream>

class TempClass
{
private:
    const int a;
    const int b;
public:
    TempClass() : a(100), b(200) {}
    TempClass(int i, int j) : a(i), b(j) {}
    int get_a() const { return a; }
    int get_b() const { return b; }
};

int main()
{
    TempClass c;

    int &aa = *reinterpret_cast<int*>(&c);      // int &aa = *(int*)(&c);
    int &bb = *(reinterpret_cast<int*>(&c)+1);  // int &bb = *((int*)(&c)+1);
    std::cout << "before c.a : " << c.get_a() << "   c.b : " << c.get_b() << std::endl;
    aa = 300;
    bb = 400;
    std::cout << "after  c.a : " << c.get_a() << "   c.b : " << c.get_b() << std::endl;

    return 0;
}

일반적인 class인 TempClass를 정의하였고, private 멤버변수 a, b는 const 이므로 생성자에 의해서만 값이 초기화된다.

그런데 main 함수에서 생성된 클래스 인스턴스의 주소를 받았고 이를 이용하여 reinterpret_cast 를 써서 "억지로" private 멤버에 접근을 하여 참조자를 부여하였다.
(주석처리된 C 스타일의 casting 또한 결국 동일한 의미이다.)

결론은... 역시 정상적으로 컴파일되며 값 또한 변경이 된다.

....................

C, C++ (뿐만 아니라 어느 언어로 프로그래밍을 하든 비슷한 이야기지만) 프로그래밍에서 사용되는 키워드의 의미를 망각하거나 잘못 이해하면 안되겠다.

C, C++ 에서 사용되는 키워드인 const, private 등은 어디까지나 프로그래머를 위한 키워드이지 프로그램을 사용하는 사용자를 위한 키워드가 아니다. 즉, 프로그래머가 위와 같은 키워드를 적절히 사용하여 프로그래밍을 하면, 나중에 그 소스코드를 이용할 때, 혹은 다른 사람이 그 소스코드를 활용할 때 이러한 키워드를 보고 해당 변수, 함수, 객체의 의미를 잘 정립할 수 있으며, 또한 혹시 모를 프로그램상의 오류를 미연에 방지할 수 있다는 데에 의미를 두어야 한다.

결국, 위와 같이 소스코드를 짜 보는 것은 프로그래머의 자유이고, 분명히 한번 궁금해서 실험적으로 해 볼 수 있는 시도임엔 틀림 없다. 무언가를 제한하는 키워드를 사용하는 의의를 역설적으로 음미해 보는 데에는 데에는 분명 유익한 코드이니까.

실전에서 저런 식으로 프로그래밍을 하는 것 만큼 어리석은 짓은 없을 것이다.

저것은 결코 대단한 기술도 아니며, 저걸 "private 변수에 접근할 수 있는 비법" 으로써 안다고 자랑할 만한 거리는 더더욱 아닌 것이다.

마치 뭐랄까, 박물관에 전시된 골동품에 "손대지 마시오!" 라고 적혀진 경고문구를 무시하고 자기 손때를 묻힌 후 만졌다고 자랑하는 거나 다를게 없어보인다는....

적어도 C/C++ 프로그래밍을 할때 const 와 private 등을 제대로 사용할 줄 아는 사람들에게는 저 코드는 정말 stupid한 소스코드이기에.

### Wafting ....... Done !!!
### ...
### ;;

댓글 없음:

댓글 쓰기