const 키워드를 붙이면 변수를 상수화 한다.... "상식"이 되어버렸지만 변수 이외에 포인터 , 맴버데이터 , 함수 ,객체까지 확장할경우 의미가 넓어진다. 하지만 진정한 const의 의미는 안정적인 프로그래밍 코드구현에 있다.
일단 기본 상식인 변수와 포인터 를 const화 시키는건 요약글로 묶어두고... ㅋ
const 포인터 변수 짬깐 들여다보기 ㅋㅋ
const키워드와 맴버데이터
기본적인 변수를 상수화 시키는것과 같은 이치다. 하지만 맴버데이터이니만큼 어떻게 초기화 시키는지쯤은 알고 넘어가야 하겟다.
작성법 : 일반 변수와 같이 const키워드를 앞에 붙여주면된다.
using std::cout;
using std::endl;
class test{
const int num;
public:
test(int _num){
num = _num;
}
void print(){
cout<<"num = "<<num<<endl;
}
};
int main(){
test work(10);
work.print();
return 0;
}
그래서 나온것이 "이니셜라이져" 라고하는 초기자이다.
초기자를 사용하여 const화된 맴버데이터를 초기화 하는 올바른 test 클래스
const int num;
public:
test(int _num):num(_num){
}
void print(){
cout<<"num = "<<num<<endl;
}
};
초기자는 함수의 몸체부분이 실행되기전에 먼저 실행된다.
그렇다면 왜 초기자를 사용해야할까? 클래스내부에서 초기화할순 없는건가?... 라고 생각하는 사람들이 많은데.... -ㅅ-; 구조체 내부에서 값을 초기화 할수있었나?? 불가능했다. 클래스또한 마찬가지이다.
그렇다면 왜 생성자에서 초기화 할까? 메모리구조상 객체를 찍어내는 순간 그 객체를 메모리공간에 올라가는데 이와 동시에 생성자를 호출한다. 하지만 초기자는 생성자 이전에 실행되기때문에 미리 맴버데이터를 초기화시켜줄수있게 되는것이다.
초기자의 사용방법 : 함수(자료형 매개변수) : const변수(매개변수) , ....{} 라고 적어주면된다.
ex)
const int num;
int x;
int y;
public:
test(int _num , int _x , int _y ):num(_num) , x(_x) , y(_y){
}
void print(){
cout<<num<<x<<y<<endl;
}
};
const 키워드와 맴버함수
맴버함수의 상수화는 곳 그함수내에서는 데이터에 관한 어떤 조작도 할수없을 뿐더러 값조작의 기회조차 주지 않음을 의미한다.
작성법 : const 키워드를 함수 머리 뒷부분에 적어줌으로써 함수를 상수화 시키는면된다.
using std::cout;
using std::endl;
class test{
int Notouch;
public:
test():Notouch(10){ //변수(값)은 C++스타일의 초기화방법
}
void print() const{
cout<<Notouch<<endl;
Notouch++; //컴파일 에러!!
}
};
int main(){
test work;
work.print();
return 0;
}
상수화된 맴버함수는 값 조작 권한을 잃는다.
아래 또하나의 코드를 통해 상수화된 두 함수간의 관계를 알수있다. 안봐도 되지만 본다면 ㅋㅋ
using std::cout;
using std::endl;
class test{
int Notouch;
public:
test():Notouch(10){
}
void print() const{
cout<<Notouch<<endl;
Notouch++; //컴파일 에러!!
print2(); //컴파일 에러!!
}
void print2(){
cout<<Notouch<<endl;
}
};
int main(){
test work;
work.print();
return 0;
}
컴파일에러가 뜨는이유는 print2함수에서 맴버데이터를 조작할 가능성이 있기때문이다. 프로그래머가 보기에는 print2함수에선 아무 데이터 조작도 하지않지만 컴파일러는 그렇게까지 관대하지 못하기때문에 확실함을 요구하는 차원에서 에러를 띄워주는 것이다. 또하나의 이유는 값조작이며 위에서 언급했으므로 pass~
올바른 클래스
int Notouch;
public:
test():Notouch(10){
}
void print() const{
cout<<Notouch<<endl;
//Notouch++;
print2();
}
void print2() const{
cout<<Notouch<<endl;
}
};
이를 토대로 const함수는 const함수만 호출이 가능함을 알수있다.
const 키워드와 객체
상수화된 변수처럼 사용하면된다. 상수화된 객체는 맴버데이터의 변경이 절대적으로 불가능해진다.
작성법 : const 클래스 객체;
using std::cout;
using std::endl;
class test{
const int val;
public:
test(int _val):val(_val){
}
void print() { //컴파일 에러!!
cout<<val<<endl;
}
};
int main(){
const test work(10);
work.print();
return 0;
}
이유는 즉, 상수화의 의미를 이해하면되는데,,; 값조작을 허용치않는 객체에서 값 조작이 가능한 비 상수화 함수를 호출했다고 가정할경우 맴버데이터값이 변하게되는 원치않는 일이 발생할수있기 때문이다. 컴파일러는 이런 상황이 일어나지않을수 있음에도 불구하고 자비롭지못해 에러를 내뱉는다.
여기서 또 오버로딩의 개념이 나오는데 상수화된 객체와 비 상수화된 객체가 맴버함수를 호출할때 인자값이 같을경우 어떻게 오버로딩을 하느냐?! ㅋㅋㅋ 바로 const키워드를 붙이느냐 안붙이느냐의 여부에따라 오버로딩이 되는거다.
함수의 오버로딩
using std::cout;
using std::endl;
class test{
const int val;
public:
test(int _val):val(_val){
}
void print() const{
cout<<val<<endl;
}
void print(){
cout<<val<<endl;
}
};
int main(){
const test work1(10);
work1.print();
test work2(20);
work2.print();
return 0;
}

댓글을 달아 주세요