본문 바로가기

const에 관하여

변수를 상수화 한다. 상수라는 말은 변하지 않는 것을 말하므로, 선언된 변수의 값이 변하지 않는 것을 말한다.

 

const는 변하지 않는 것이기 때문에 전역변수로 선언하면 변하지 않는 부분만을 모다놓은 CONST SECTION(SEGMENT)에 배치된다.

C++로 확장 되면서 변수 뿐만 아니라, 함수와도 결합하여 사용 한다.

 

int main(int argc, char*argv[],char**env)

{

    printf("Hello\n");

    return 0;

}

 

여기서의 빨간색 스트링은 상수 스트링 이다. 이것은 결코 변하지 않아야 하므로 CONST 영역에 배치 한다. CPU을 설계하면 ROM영역이나 FLASH영역에 배치되어 동작 시킬 수 있다. 프로그램 코드 영역이 RAM에 전송(OS, 윈도우,리눅스)되어 동작한다면, 모든것이 RAM 존재하므로 이것 역시 RAM 영역이다. 그러나 CPU의 프로그램에서는 전원이 나가도 지워지지 않는 영역에 존재한다. 

 

이제 변수의 경우를 보면

 

const double pi = 3.14159264358;

변수 pi는 값이 변하지 않는 변수로 정의 하라는 말이다.

 

pi = 180.;

 

이렇게 되면 값이 변하는 것이므로 컴파일러에서 에러를 출력 한다.

 

결국 이것은

 

#define  PI 3.14159264358

#define  pi 3.14159264358

 

이것과 다를 것 없다. 그러나 const변수는 조금 차이가 있다.

 

'#define'을 전처리기에서 바로 숫자로 바꾸어 처리 하기 때문에 어떤 테이블도 없다. 따라서 이것은 디버깅 과정에서 어떤 값이 PI인지 알수가 없다. 따라서 이것을 디버깅의 테이블에 존재하게 하여 디버깅 과정에서 값을 표시하는 등의 처리가 가능하다.

enum도 역시 위와 같은 이유로 define을 대체해서 사용한다.

 

#define  PI 3.14159264358

 

int main()

{

    double rad;

    scanf("%lf", &rad);

 

    rad *= PI; rad /= 180.;

 

    if (rad >= 3.14159264358)

      printf("PI보다 크거나 같다.\n");

   

    return 0;

}

컴파일 시, 전처리 과정을 거치면 두개가 차이가 나지 않는다. 디버깅 체계에서 완전히 PI가 없어진다.

 

 

const는 고정된 값을 원할 때, 모든 파입의 변수에서 사용할 수 있다.

 

 

 

 

 

몇가지 예 :

 

case 1:

 

const int ival = 10;

ival = 20;  ---> 에러

 

case 2:

 

int idata;

const int *pdata = &idata;

*pdata = 10;  ---> 에러 : 값을 변화하지 말라.

int a = 20;

pdata = &a; ---> 값이 아니라 변수의 위치 주소값을 처리하는 포인터 변수이기 때문에 가능.

printf("Data=%d\n", *pdata );

 

case 3:

 

int idata = 10;

int * const pdata = &idata;  ---> pdata의 값을 변화하지 말라. 즉, 포인터의 값을 변화지 말라는 말이다.

*pdata = 10;  ---> 정상 : 값을 변화 가능.

int a = 20;

pdata = &a; ---> 에러 : 주소값을 변화 불가능.

 

case 4:

 

int idata = 10;

const int * const pdata = &idata;  ---> 이 변수의 값과 pdata의 값인 포인터값도 변화하지 말라.

*pdata = 10;  ---> 에러 : 값을 변화 가능.

int a = 20;

pdata = &a; ---> 에러 : 주소값을 변화 불가능.

printf("Data=%d\n", *pdata );

 

const int * const pdata;

이렇게 초기값을 넣지 않으면 포인터 값을 변화 시킬 수 없으므로 의미가 없어지고, 사용할 수 없다.

 

 

함수에서 상수  const 사용

 

출처 : http://blog.naver.com/pointer98/150044038577

 

멤버함수의 상수화

 

class TstConst
{
public:
   int a;  //멤버 변수

   void funcA(TstConst * pTest) const;  //상수화된 멤버 함수
   void funcB(int b);          //일반 맴버 함수
   void funcC(int c) const;   //상수화된 멤버 함수

};

void TstConst::funcB(int b)          //일반 맴버 함수
{
         b = 1;
}  
void TstConst::funcC(int c) const   //상수화된 멤버 함수

         c = 1;
}

void TstConst::funcA(TstConst * pTest) const
{
    int b = 1;  //내부에 선언한 변수의 값을 변경 할 수 있다.
    a = 1;        // 컴파일 에러 : 멤버변수 값을 변경 할 수 없다.
    pTest->a = 1;  //클래스 포인터를 사용하여 멤버 변수의 값을 변경 할 수 있다. 
                             그러나 이것은 바람직하지 않은 사용이다. 
        이렇게 사용할 바에는 그냥 일반함수로 만들어 사용하는 게 낮다.
    funcB(2);  //컴파일 에러 : 상수화가 안된 맴버함수를 사용할 수 없다.
    funcC(2);  //상수화된 멤버함수로 컴파일된다.
}

 

const와 함수 오버로딩

 

const 사용에 따라 동일한 함수명과 동일한 매개변수를 가지고 있다하여도 함수오버로딩이 가능하다.

 

void funcA(void);  //일반 함수
void funcA(void) const;  //const를 사용한 함수오버로딩된 상수 함수

void funcB(void)
{
     funcA();  //일반 함수가 실행된다. 상수함수도 실행할 수 있지만 우선순위가 일반함수가 더 높다.
}
void funcC(void) const
{
     funcA();  //상수 함수가 실행된다. 오직 상수함수만을 실행 할 수 있다.
}

 

----------------------------------------------------------------------------------

 

출처 : http://decdream.tistory.com/224

 

#include <iostream> 
using namespace std;

class A 
{

private: 
   int x; 

public: 
   A():x(0){}

 

   // --------------------------------------------------------------

   // 방식은 아무영향도 줄 수 없다. 이는 일반함수에서의 경우와 동일하다. 
   // 결국 함수의 리턴값 앞,뒤에 쓰는 const는 별 영향력이 없다.

   const int foo() {

         cout << "const int foo() : ";

         return ++x;

   }  
   

   int const hoo() {

         cout << "int const hoo() : ";

         return ++x;

   } 

 

   // --------------------------------------------------------------

   //내부에서 맴버변수가 const임을 보여준다. 

   //  const형태로 정의되어 있는 koo를 일반객체 a로 호출했을때에도 호출이 가능하며, 
   //  반대로 const객체 b에서는 const멤버함수가 아닌 foo(), hoo()는 호출할 수 없다. 
   //  즉, const객체에서는 const멤버함수만을 부를 수 있다. 
   int koo() const {

          cout << "int koo() const : ";

          return x;

   }

 

   // --------------------------------------------------------------

   //내부에서 맴버변수가 const임을 보여준다. 

   //  C++은 const멤버함수에 대해 오버로딩을 지원한다. 
   //  일반객체에서 a.goo를 호출했을때는 int goo()가 호출되며 
   //  const객체에서 b.goo()를 호출했을때는 int goo() const가 호출된다. 


   int goo() 

   { 
        cout << "int goo() : "; 
        return ++x; 
    } 

    int goo() const  // 5번

    { 
        cout << "int goo() const : "; 
        return x; 
     }

};

 

void main() 

   A a; 
   cout << a.foo() << endl; 
   cout << a.hoo() << endl; 
   cout << a.koo() << endl; 
   cout << a.goo() << endl;

   cout << endl << "const 객체 생성" << endl;

 

   const A b;

   //cout << b.foo() << endl; 
   cout << b.goo() << endl; 
   cout << b.koo() << endl; 
}

'' 카테고리의 다른 글

const에 관하여  (0) 2011.05.19