우선..
C++에서 CTest라는 클래스가 있을 경우 해당 객체에 대한 선언은 다음과 같이 할 수 있다.
CTest test1, test2;
이 경우에 const를 붙여 쓰는 사람은 아마 거의 없을 것이다 -.-;; 그럴거면 왜 만들었어.. 만약 저 앞에
const CTest test1, test2; 이런식으로 const를 붙였다면 더이상 해당 객체는 변경을 할 수 없게 된다.

자 그럼 const가 사용되는 다양한 예를 쭉 적어보자

const CTest* pTest = new CTest; //이건 CTest const *pTest = new CTest; 와 같다
CTest* const pTest = new CTest;
const CTest* const pTest = new CTest;

int CTest::TestMethod0(int a, int b) const .... //CTest안의 내부 메소드. TestMethod0에서는 CTest의 멤버 변수의 값을 변경 할 수 없다.
int TestMethod1(const CTest* pTest) ... //인자로 받은 pTest가 참조하는 객체의 값을 바꿀 수 없다.
int TestMethod2(CTest* const pTest) ... //pTest가 다른 객체를 잠조 할 수 없다
int TestMethod3(const CTest* const pTest) ... //pTest는 다른 객체를 참조할 수도, 값을 바꿀 수도 없다.
//객체 내용을 전혀 바꾸지 않고 그냥 안의 내용을 참조, 이용하기만 할 것이라면 위처럼 하는게 제일 바람직하다.

//const는 사용할 수 있는 한 남발을 하자!!! 특히 파라미터로 받을 경우 남발하자.
//또한 멤버 변수를 바꾸지 않는 메소드에서도 무조건 const를 써주자. 습관 들이는게 좋다.

우선
const CTest* pTest = new CTest; 이건
pTest가 참조하는 CTest 객체에 const가 걸린 것이다. 즉, pTest가 가리키고 있는 객체 안의 값을 바꿀 수 없다.
위 처럼 선언 돼 있는 경우 pTest->a = 3; 이런식으로 내부의 값을 바꾸는건 컴파일러의 제약 사항에 걸리는 일이다.

그럼 CTest* const pTest = new CTest;는 뭘까?
이건 CTest*에 const가 걸린 것이다.
포인터라는 것은 그냥 주소값을 갖고 있는 32bit변수(32bit CPU일 경우)일 뿐이다. 즉 CTest*라는 것은 CTest 객체가 담긴 장소를 가리키는 32bit 변수일 뿐이라는 것이다. 예를 들어 new CTest로 생성한 객체가 0x01010101번지에 자리잡고 있을 경우 CTest* pTest에서 pTest의 값은 단지 0x01010101 일 뿐이다.
즉, CTest* const.... 라는 구문은 pTest를 바꿀 수 없다는 말이며(pTest가 가리키는 값을 바꿀 수 없다는 말), 이 말인즉슨 안에 들어있는 0x01010101을 바꿀 수 없다는 말이다. 즉, 클래스의 포인터 앞에 const가 붙을 경우, '다른 객체를 참조 할 수 없'게 된다.
CTest* const pTest1 = new CTest;
CTest* const pTest2 = new CTest;
가 있을 경우
pTest1 = pTest2;
이런건 안된다.
하지만 pTest1이 const로 묶여 있다 하더라도
pTest1->SetValue(3); 이런식으로 객체 내의 값은 마음대로 바꿀 수 있다. 안에 있는 객체에 const가 걸린 것이 아니기 때문에!!!

이제 const가 많이 쓰이는 곳이 파라미터로 사용 될 때인데, 메소드에서 넘겨받은 파라미터를 딱히 바꾸지 않아야 할때는 const를 붙여주자. 그냥 가능한한 const는 남발하자.


이제 Java를 보자.
자바의 클래스 객체 생성은 다음과 같이 한다
Test test = new Test();
그렇다면 이제, C++의 const와 비슷한 final을 사용해보자.


final Test test1 = new Test();
final Test test2 = new Test();
public final method1() ...

비슷하게 생겼지만 아쉽게도 역할이 조금 다르다.
final Test test1 = new Test();  이 부분에 쓰인 final은, 객체에 final을 거는 것이 아니다. 즉, final로 잠겨있다고 해도 test1.setValue(1); 처럼 객체 안의 내용을 바꿀 수 있다.
하지만 test1 = test2; 처럼 객체를 다른 객체로 변경 하는 것은 안된다. 쉽게 생각해서 mutable class에서는 final을 설정해도 안의 내용을 맘대로 바꿀 수 있으며, 객체를 다른 것으로 바꾸는 것만 안된다.

뭐 사실 immutable class에서도 마찬가지이긴 하다. 하지만 꼭 동작하는 건 내용이 안바뀌는 듯한 느낌이다.
예를 들어 대표적인 immutable class인 String을 보면
final String strTest = "This is the test.";
가 있는데 strTest += "which is being made by roter";
이건 안된다!! 꼭 안의 내용을 바꾸는 것 같지만 String 은 immutable class이기 때문에 이런 동작은 되질 않는다. (immutable이 궁금하면 구글링 ㄱㄱ)

그리고 자바에서 클래스 내의 메소드에 final을 붙이는 경우가 있는데, 이경우는 C++처럼 멤버 변수의 변경 막기 이런 거창한게 아니고 그냥 자식 class에서 override가 안되게 막는거다.

결론은...........
JAVA에서의 final Test test1 = new Test();는 C++에서의 CTest* const pTest1 = new Test(); 와 동치이다. 객체 변경 막기!!!
끝.

저작자 표시 비영리 변경 금지
신고
블로그 이미지

roter

JHB / Peripheral Programmer

댓글을 달아 주세요

  • BlogIcon roter 2012.07.18 22:45 신고  댓글주소  수정/삭제  댓글쓰기

    이제와서 다시 읽고 느낀건.. CTest* const pTest 같은 경우는 pTest에 const가 걸렸다고 생각한다면, pTest의 내용을 바꿀 수 없는 것!이라고 생각하게 되므로(됨으로?) 기억하기 더 간결한 듯 하다.