승1's B(log n)

const 개념 확실히 잡기 본문

C&C++

const 개념 확실히 잡기

승1이 2022. 10. 13. 01:09

C++이나 C를 공부하다보면 const keyword가 많이 등장하곤 한다. 사실 그동안 과제를 할 때나 수업을 들을 때나 const라는 키워드만 보면 두려웠다. const의 개념을 확실히 이해하지 못하고 그저 상수화 해주는 키워드라고만 알고 있었기 때문이다. 따라서 이번 기회에 const에 대해 확실하게 알아보고자 한다.

 

1) const 키워드의 개념 : const 키워드는 값을 상수로 선언할 수 있도록 도와주는 키워드이다. const 키워드를 통해 한 번 설정된 값은 read-only memory에 저장된다. 따라서 상수화된 이후에는 값을 변경할 수 없다.

 

2) const 키워드는 포인터 선언에도 사용할 수 있다.

#include <iostream>
using namespace std;

int main(void) {
    char ch = 'c';
    const char* ptr;	#const를 통한 포인터 변수 선언
    ptr = &ch;
    cout << ch << endl;
    cout << *ptr << endl;
    return 0;
}

 3) const의 위치에 따른 쓰임새의 차이

* 기본적인 문법 : const는 자신의 왼쪽에 있는 것에 대해서 상수화시킨다. 그러나 만약 왼쪽에 아무것도 없다면 오른쪽에 있는 것을 상수화시킨다. 상수형 포인터는 선언과 동시에 초기화를 해줘야 한다.

  1. const char* : 상수형 문자에 대한 포인터(const 왼쪽에 아무것도 없기 때문에 오른쪽에 있는 문자를 상수화시켰음), 포인터가 가리키는 변수의 값을 바꿀 수 없다. 그러나 포인터가 가리키는 주소는 바꿀 수 있음. / char const*와 같은 의미를 가짐.
  2. char* const : 문자에 대한 상수형 포인터(const 왼쪽에 *, 포인터가 있기 때문에 포인터를 상수화시켰음), 포인터가 가리키는 주소값을 바꿀 수 없음. 그러나 포인터가 가리키는 변수의 값은 바꿀 수 있음.  
  3. const char* const : 상수형 문자에 대한 상수형 포인터(앞에 있는 const의 오른쪽에는 문자, 뒤에 있는 const의 왼쪽에는 포인터가 있기 때문에 문자와 포인터 모두 상수화시켰음) 포인터가 가리키는 변수의 값과 주소값을 바꿀 수 없음.
#include <iostream>
using namespace std;

int main(void) {
//const char*에 대한 예시(상수형 문자에 대한 포인터)
    char ch1 = 'a';
    char temp1 = 'x';
    
    const char* ptr1;
    ptr1 = &ch1;
    cout << *ptr1 << endl;
    
    //*ptr1 = 'd';   //상수형 문자에 대한 포인터이므로 문자의 값 변경 불가능
    
    ptr1 = &temp1;  //그러나 포인터 주소값 변경은 가능
    cout << *ptr1 << endl;
    
//char* const에 대한 예시(문자에 대한 상수형 포인터)
    char ch2 = 'b';
    char temp2 = 'y';
    
    char* const ptr2 = &ch2;    //선언과 동시에 초기화해야 함
    cout << *ptr2 << endl;
    
    //ptr2 = &temp2;    //문자에 대한 상수형 포인터이기 때문에 포인터 주소값 변경 불가능
    
    *ptr2 = 'd';    //그러나 문자의 값은 변경 가능
    cout << *ptr2 << endl;
    
//const char* const에 대한 예시(상수형 문자에 대한 상수형 포인터)
    char ch3 = 'c';
    char temp3 = 'z';
    
    const char* const ptr3 = &ch3;
    cout << *ptr3 << endl;
    
   // *ptr3 = 'd';  //문자의 값 변경 불가능
    
    //ptr3 = &temp3;    //포인터의 주소값도 변경 불가능
    return 0;
}

4) const로 선언된 객체는 오직 const 멤버 함수만 호출할 수 있다.

#include <iostream>
using namespace std;

class Student{
private:
    string name;
    char sex;
    int age;
public:
    Student();
    Student(string name, char sex, int age) : name(name), sex(sex), age(age){}	//멤버 이니셜라이저를 통한 멤버 변수 초기화
    
    void gettingOld(){
        age++;
        cout << "I became " << age << " years old now." << endl;
    }
    void Introduce() const{	//const 멤버 함수
        cout << "Hi, my name is " << name << "." << endl;
        cout << "I am " << age << " years old." << endl;
    }
    
};
int main(void) {
    
    Student Jack("Jack", 'M', 19);
    Jack.Introduce();
    Jack.gettingOld();
    
    cout << endl;
    const Student Kyla("Kyla", 'F', 20);	//const Student 객체 생성
    Kyla.Introduce();	//const 멤버 함수만 호출 가능
    //Kyla.gettingOld(); //const 멤버 함수가 아니므로 호출 불가능
    return 0;
}

5) const 멤버 함수

  1. const 멤버 함수 선언법 : int GetAge() const; 자료형 함수이름 뒤 const 키워드. 앞서 언급했듯이 const는 왼쪽에 있는 것을 상수화하기 때문에 여기서는 함수를 상수화하기 위해 맨 마지막에 적음.
  2. const 멤버 함수 안에서는 모든 멤버를 상수화하기 때문에 const 멤버 함수 안에서 값 조작시 에러가 남. ex) void ageTo25() const{ age = 25; // 에러 발생}
  3. 따라서 const 멤버 함수 안에서 함수를 호출하기 위해서는 호출되는 함수도 const 멤버함수여야 함.
#include <iostream>
using namespace std;

class Student{
private:
    string name;
    char gender;
    int age;
public:
    Student();
    Student(string name, char gender, int age) : name(name), gender(gender), age(age){}
    
    void myGender() //const 멤버 함수가 아님.
    {
        cout << "My gender is " << gender << "." << endl;
    }
    void gettingOld(){
        age++;
        cout << "I became " << age << " years old now." << endl;
    }
    void Introduce() const{
        cout << "Hi, my name is " << name << "." << endl;
        cout << "I am " << age << " years old." << endl;
        myGender(); //myGender 멤버 함수가 const가 아니기 때문에 호출 불가.
    }
    
};
int main(void) {
    
    Student Jack("Jack", 'M', 19);
    Jack.Introduce();
    Jack.gettingOld();
    
    cout << endl;
    const Student Kyla("Kyla", 'F', 20);
    Kyla.Introduce();
    return 0;
}

위의 코드에서는 Student 클래스 안에 들어있는 myGender 멤버 함수가 const가 아니었기 때문에 Introduce()라는 const 멤버 함수 안에서 호출이 불가하다. 따라서 아래와 같이 수정해주어야 한다.

#include <iostream>
using namespace std;

class Student{
private:
    string name;
    char gender;
    int age;
public:
    Student();
    Student(string name, char gender, int age) : name(name), gender(gender), age(age){}
    
    void myGender() const//const 멤버 함수로 선언
    {
        cout << "My gender is " << gender << "." << endl;
    }
    void gettingOld(){
        age++;
        cout << "I became " << age << " years old now." << endl;
    }
    void Introduce() const{
        cout << "Hi, my name is " << name << "." << endl;
        cout << "I am " << age << " years old." << endl;
        myGender(); //myGender 멤버 함수가 const이기 때문에 호출 가능.
    }
    
};
int main(void) {
    
    Student Jack("Jack", 'M', 19);
    Jack.Introduce();
    Jack.gettingOld();
    
    cout << endl;
    const Student Kyla("Kyla", 'F', 20);
    Kyla.Introduce();
    return 0;
}

참고자료 :

https://simplesolace.tistory.com/entry/c-항상-헷갈리는-const-위치에-따른-쓰임새-차이-const-char-char-const

 

[c++] 항상 헷갈리는 const 위치에 따른 쓰임새 차이 (const char , char const)

■ ( const char * ) 상수형 문자에 대한 포인터. 포인터가 가리키는 변수의 값을 바꿀 수 없음 #include int main() { char ch1 = 'a'; char ch2 = 'b'; const char * pch; pch = &ch1; std::cout << *pch << s..

simplesolace.tistory.com

https://sanghunka.tistory.com/8

 

[C] const char* 와 char const*는 같다. 왜?

💡 const는 왼쪽으로 작용하는 keyword이다. 왼쪽에 아무것도 없다면 오른쪽으로 작용한다. const의 위치에 따라 어떻게 다른지 정리해보자. 세 줄 요약 const char* 와 char const*는 같다. 왜? const키워드

sanghunka.tistory.com

https://learn.microsoft.com/en-us/cpp/cpp/const-cpp?view=msvc-170 

 

const (C++)

Learn more about: const (C++)

learn.microsoft.com

 

열혈 C++ 프로그래밍 윤성우 저 - 오렌지미디어

'C&C++' 카테고리의 다른 글

C++ STL 정리  (0) 2022.08.12
Comments