본문 바로가기

Programming/C / C++

[C++] 클래스에서의 멤버 변수, 멤버 함수의 상수화 (const의 사용법)

 일단 const에 대해서는 이미 언급을 해 놓았죠.  [C/C++] 콘스트(const)란? (←링크 참조) 그럼 C++에서 클래스라는 곳에서는 어떻게 쓰이는지 한번 알아 보도록 하겠습니다. 

 const 멤버 변수  
 : 우선 예제를 먼저 보도록 하겠습니다.
 Student라는 클래스의 id라는 멤버 변수를 const로 선언을 했습니다. 우리 일상생활에서도 보듯이 id라는 것은 고유 숫자로 부여를 받거나 하죠. 하지만 여기 Student 생성자 부분에서 에러를 발생하게 됩니다. 일반적으로 클래스에서의 객체 생성 순서에 제일 처음으로 하는 것은 바로 "메모리 공간의 할당"입니다. 
  생성자가 호출되지 않는 상태에서, 메모리 할당되는 순간 name, age,  id 뭐 이런 것들이 초기화 됩니다. (일단 우리가 원하는 값이 아닌 쓰레기 값으로 채워지게 되죠) 하지만 이렇게 id에 쓰레기 값으로 채워 진다면, const 선언을 했기 때문에 id는 아예 이 쓰레기 값으로 초기화 되어서 두번 다시 바꾸지 못하게 되고, 결국 에러가 납니다. 
 우리는 위 예제를 통해서  const 멤버 변수는 생성자 내에서 초기화 시킬 수 없음을 알았습니다. 그럼 어떻게 해야 할까요? 이 문제를 해결하기 위한 방법으로 등장한 문법적 방법이 바로 initializer입니다. 
  바로 생성자의 꺽쇠 안의 몸체 부분이 아니라, 그 사이에  : id(_id) 이런식으로 선언하는 방법이다. (이 부분은 생성자 호출 되기 이전에 완료가 되게 됩니다.) 멤버 변수 id를 Student 생성자 호출될때 인자로 전달되었던 _id로 초기화 해라 라는 의미이다. 

 const 멤버 함수  
 : 그럼 클래스의 멤버 함수에 const를 붙인다는것은 어떤 의미를 가질까요? 바로 아래와 같은 의미를 가집니다. 
멤버 함수에 const를 붙인다는 것은 멤버 변수의 값의 변경을 허용하지 않음은 물론이고, 멤버 변수값의 변경에 대한 기회도 제공하지 않겠다
 const를 쓴 멤버 함수의 간단한 예제를 보겠습니다 .
 여기서는 Showdata()라는 함수를 const 시켰습니다. 그래서 함수 내에서 만약 주석부분과 같이 값의 변경을 한다고 하면, 에러를 발생하게 됩니다. 더욱 자세한 것은 다음 예제를 통해서 알아 보겠습니다. 
 에러 첫번째, 위의 10번째줄 Compile Error 부분은 멤버 변수 조작은 안하지만, 멤버 변수를 조작할수 있는 기회제공을 하고 있습니다. 여기에서 GetPtr() 함수는 cnt를 포인터를 리턴해 주고 있는데, 만약 누군가가 Getptr을 호출한후 ,cnt의 포인터를 얻어낸다고 한다면, cnt 포인터를 얻어낸 사람은 포인터를 통해 얻은 cnt의 주소값을 통해서 cnt의 값을 조작할 수 있다는 것입니다.  
  결국, getptr()함수는 간접적으로 멤버 변수의 조작 동기를 제공한 것입니다. 그래서 compile error가 발생합니다. 이 컴파일 에러를 피하기 위해서는 const를 더 추가해주면 됩니다. 바로 아래와 같이 말이죠. 
  int* 앞에 const가 붙으면 포인터가 가리키는 곳은 상수화 시키는 데이터 상수화를 하겠다는 거죠. 그래서, 이 포인터를 얻은 영역에서는 cnt라는 변수에 접근은 가능하지만, 변경을 불가능하게 만드는 것입니다. 

 다음 에러 두번째, 바로 Showdata()함수 안에 Showintro()함수 호출 부분입니다. 
 프로그래밍에서 런타임, 컴파일 타임에 결정되는 요소들이 있는데, 값이 변경되느냐는 사항은 런타임에 결정되는 요소이고, 컴파일러는파일 타임에 Showintro 라는 함수를 어디까지 이해하느냐 하면은, 이 함수가 상수화 되지 않는 일반적인 함수라고 인식을 하게 됩니다. 
 그래서 Showdata() 함수 내부에서 Showintro() 함수 부분을 호출 할때, 컴파일러는 Showintro 함수의 내부를 검사하는 것이 아니라, showintro가 상수화 된 함수인지 아닌 함수인지만 분석해서, 이 함수가 상수화 되어 있으면 멤버 조작할 가능성이 없다고 인식하겠지만, 지금 예제에서는 컴파일러는 showintro가 상수화가 되지 않앗다는 것만 인식하기 때문에 컴파일 에러가 나는 것입니다. 
  const를 빼는 것도 한 방법이겠지만, 굳이 const를 뺄 필요는 없겠죠? 다음과 같이 Showintro 함수도 const를 붙여 줍니다. 
 그러면 컴파일러가 Showintro가 상수화 되었다고 인식을 하게 되어서 컴파일단에서 에러가 나지 않게 되는 것이죠. 자 완성된 예제입니다.