2004년 11월 4일 목요일

C++ const

1) pointer to const

const int*와 int const*는 모두 const int를 가리키는 pointer다.
가리키는 변수는 const이지만 pointer자체는 const가 아니기 때문에 다른 것을 가리킬 수 있다.

a, b, *c, *d의 값을 바꿀 수 없고
c, d 는 바꿀 수 있다.

const int*나 int const*는 const가 아닌 int를 가리킬 수도 있다.
단, 가리키는 것이 const가 아닐 때에도 modify는 안된다.

예제)
#include <iostream>
using namespace std;

int main()
{
    const int a = 10;
    const int b = 20;

    const int* c;
    int const* d;

    c = &a;
    d = &a;
    cout << "c : " << *c << endl;
    cout << "d : " << *d << endl;

    c = &b;
    d = &a;
    cout << "c : " << *c << endl;
    cout << "d : " << *d << endl;

    return 0;
}

2) const pointer
const pointer는 한 번 가리키면 다른 것을 가리킬 수 없다.
선언 시점에 초기화도 해야 한다.

int a = 10;
int* const c = &a;

a, *c는 modify 가능
c는 modify 불가

3) const pointer to const
const int a = 10;
const int* const c = &a;
int const* const d = &a;

a, c, d, *c, *d는 modify 불가능

4) *과 const의 위치
* 뒤에 const가 붙으면 const pointer가 되고 그 이외의 위치에 const가 붙으면 pointer to const가 됨.

5) const임을 compiler가 check하지 못하는 경우
compiler는 통과했으나, 결과는 이상하게 나올 수 있음.

예)
#include <iostream>
using namespace std;

int main()
{
    const int a = 2;

    int* b = (int*)&a; // (legal but bad practice)

    cout << "&a : " << &a << endl;
    cout << "a : " << a << endl;
    *b = 20;

    cout << "b : " << b << endl;
    cout << "*b : " << *b << endl;
    cout << "&a : " << &a << endl;
    cout << "a : " << a << endl;

    return 0;
}

$ ./a.out
&a : 0xbffff894
a : 2
b : 0xbffff894
*b : 20
&a : 0xbffff894
a : 2

분명 a와 *b가 같은 메모리 주소 임에도 다른 값을 출력한다.
이것은 *b에 20을 넣을 때 컴파일러를 속여서 const memory공간에 값을 넣은 것이고
그럼에도 불구하고 마지막에 a가 2로 나온 것은 compiler가 compile시나 혹은
최적화 과정에서 미리 2로 값을 적어두었기 때문인 것으로 보임.

6) call by value나 return by value에서 const의 의미는 그 variable이 lvalue가 되는 것을 막는 역할 밖에 하지 못함. 왜냐하면 call by value나 return by value는 값을 복사하기 때문에 값을 다른 변수에 받은 후 값을 받은 변수를 수정하면 됨.

7) temporary object는 자동으로 const임.
   (temporary object는 compilter가 알아서 처리하고 user는 볼 수 없으므로)

참고 서적
Thinking in C++, Chapter 8. Constants

댓글 없음:

댓글 쓰기