본문 바로가기
Develop/C++

[C ++] 상수형 메소드

by J-rain 2023. 2. 3.

상수형 메서드 혹은 상수화된 메서드는 멤버 변수에 읽기 접근은 가능하나 쓰기는 허용되지 않는 메서드를 말한다.

여기서 '쓰기'란 각종 대입 연산자나 단항 연산자 등을 사용하는 것을 말한다. 선언 방법은 함수 원형 뒤에 형한정어인 const 예약어만 붙이면 된다.

#include <iostream>
using namespace std;

class RAIN
{
 public:
   RAIN(int Param) : Data(Param) { };
   ~RAIN() { }
   
   int GetData() const   // const 예약어
   {
     // 멤버 변수의 값을 읽을 수는 있지만 쓸 수는 없다.
     return Data;
    }
    
    int SetData(int Param) { Data = Param; }
    
 private:
   int Data = 0;
 };
 
 int main(void)
 {
   RAIN r(10);
   cout << r.GetData() << endl;
   
   return 0;
}

실행결과

만약  12번행에 SetData(20);  을 선언하면
 
오류 메세지가 'this' 포인터를 들먹이는 것을 볼 수 있는데 사실 상수화하는 방법이 'this 포인터를 상수형 포인터로 변경하는 것'이다. 코드로 말하면 this 포인터의 형식이 RAIN *this; 가 아니라 const RAIN *this; 이다.

그러므로 다음과 같이 대입 연산자를 사용하여 '쓰기'도 안된다.
12번행에 Data = 20; 을 선언하면
컴파일 오류가 나는것을 확인할 수 있다.
상수형 메서드는 절대로(혹은 문법적으로) 멤버 변수의 값을 쓸 수 없고, 상수형 메서드가 아닌 멤버는 호출할 수 없다.

상수형 메서드의 예외 상황

 

mutable 예약어와 C++ 전용 형변환 연산자인 const_cast< > 를 사용하는 방법을 보자면

#include <iostream>
using namespace std;

class Rain
{
 public:
   Rain(int Param) : Data(Param) { };
   ~Rain() { }
   
   //  상수형 메서드로 선언 및 정의했다.
   int GetData() const
   {
   
    //상수형 메서드라도 mutable 멤버 변수에는 값을 쓸 수 있다.
    Data = 20;
    
    return Data;
   }
   int SetData(int Param) { Data = Param ;}
 
 private:
   mutable int Data = 0;  // mutable 사용
};

int main(void)
{ 
  Rain r(10);
  cout << r.GetData() << endl;
  
  return 0;
 }

실행결과

이처럼 mutable로 선언한 멤버 변수의 값은 상수형 메소드라해도 쓰기가 허용된다.

 

또한 상수형 '참조'인 경우 참조자를 통해 참조 원본에 접근하더라도 '쓰기'가 불가능하다. 그러나 const_cast< >를 사용하여 이를 가능하게 할 수 있다.

#include <iostream>
using namespace std;

void TestFunc(const int &Param)
{
  // 상수형 참조였으나 일반 참조로 형변환했다.
  int &newParam = const_cast<int &> (Param);

  // 따라서 l-value가 될 수 있다.
  newParam = 20;
}

int main(void)
{
 int Data = 10;
 
  // 상수형 참조로 전달하지만 값이 변경된다.
  TestFunc(Data);
  
  // 변경된 값을 출력한다.
  cout << Data << endl;
  
  return 0;
 }

실행결과

 

'Develop > C++' 카테고리의 다른 글

[C ++] 변환 생성자  (0) 2023.02.04
[C ++] 복사 생성자  (0) 2023.02.04
[C ++] 생성자와 소멸자  (0) 2023.02.03
[C ++] 접근 제어 지시자  (0) 2023.02.03
[C ++] 클래스 기본 문법  (0) 2023.02.03

댓글