const란 const로 정의된 변수를 상수화하여, 그 값을 변경하지 못하게 하는 것이다.

변경하지 않아야 하는 변수를 수정하여, 난 에러는 찾기가 매우 힘들다. 이러한 변수사용시 그값이 변경되지 않아야 하는 곳에 사용하여, 그러한 에러를 컴파일시 확인이 가능하게 하게 한다.

 

#변수의 상수화

const [변수 타입] [변수명] =  초기화 값 ;  //선언시 초기화 값을 넣어야 된다. 초기화 값을 넣은 후 변경을 할 수 없다.

ex>

const int A = 12345;  //A를 상수화하여 12345값으로 상수화(고정)된다.

const float B = 123.45;  //B를 상수화하여 123.45값으로 상수화(고정)된다.

 

const [변수 타입] * [변수명];  //변수명이 가리키는 주소의 값을 변경할 수 없다.

ex>

const int * pA;

int a = 3;

pA = &a;   //pA에 a의 주소값을 넣는다.

*pA = 10;  //컴파일 에러 : pA가 가리키는 주소의 값이 상수화 되어 변경할 수 없다.

 

[변수 타입] * const [변수명] = 초기화 값;  //변수명이 가리키는 주소를 변경할 수 없다.

ex>

int a;

int * const pA = &a;

pA = &a;   //컴파일 에러 : pA가 가리키는 주소가 상수화되어 변경할 수 없다.

*pA = 10;  //pA가 가리키는 주소의 값을 변경한다.

 

const [변수 타입] * const [변수명] = 초기화 값;  //변수명이 가리키는 주소와 그주소의 값도 변경할 수 없다.

ex>

int a;

const int * const pA = &a;

pA = &a;   //컴파일 에러 : pA가 가리키는 주소가 상수화되어 변경할 수 없다.

*pA = 10;  //컴파일 에러 : pA가 가리키는 주소의 값이 상수화 되어 변경할 수 없다.

a = 3;  //이렇게 직접 값을 변경하는 수 밖에 없다.

 

#멤버함수의 상수화

[리턴타입] [함수명] (매개변수) const {함수내용...};  //해당 함수안에서는 클래스의 모든 멤버 변수는 상수화되어 값을 변경할 수 없고, 포인터 반환이 되지 않는다. 또한 멤버함수의 경우 같이 상수화된 함수만을 사용할 수 있다.

ex>

int a;  //멤버 변수

void FunctionA(Test * pTest) const;  //상수화된 멤버 함수

void FunctionB(int b) { b = 1; };  //일반 맴버 함수

void FunctionC(int c) const { c = 1; };  //상수화된 멤버 함수

 

void Test::FunctionA(Test * pTest) const

{

  int b = 1;  //내부에 선언한 변수의 값을 변경 할 수 있다.

  a = 1;  //컴파일 에러 : 멤버변수 값을 변경 할 수 없다.

  pTest->a = 1;  //클래스 포인터를 사용하여 멤버 변수의 값을 변경 할 수 있다. 그러나 이것은 바람직하지 않은 사용이다. 이렇게 사용할 바에는 그냥 일반함수로 만들어 사용하는 게 낮다.

  FunctionB(2);  //컴파일 에러 : 상수화가 안된 맴버함수를 사용할 수 없다.

  FunctionC(2);  //상수화된 멤버함수로 컴파일된다.

}

 

#const와 함수 오버로딩

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

ex>

void FunctionA(void);  //일반 함수

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

 

void FunctionB(void)

{

  FunctionA();  //일반 함수가 실행된다. 상수함수도 실행할 수 있지만 우선순위가 일반함수가 더 높다.

}

void FunctionC(void) const

{

  FunctionA();  //상수 함수가 실행된다. 오직 상수함수만을 실행 할 수 있다.

}



#include <iostream>

#include <list>

using namespace std;


bool Predicate(int n){

    return n >= 30;

}


int main(){


    list<int> lt;


    lt.push_back(10);

    lt.push_back(20);

    lt.push_back(30);

    lt.push_back(40);

    lt.push_back(50);


    list<int>::iterator iter;

    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    iter = lt.begin();

    iter++;

    iter++;


    // erase 삭제

    list<int>::iterator iter2 = lt.erase(iter);

    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;

    cout << "iter2 : " << *iter2 << endl;


    lt.push_back(10);

    lt.push_back(10);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    // 리스트에서 원소 10 제거

    lt.remove(10);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;



    // Predicate 함수에 해당하는 원소 제거 (30보다 크다)

    lt.remove_if(Predicate);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    return 0;

}

Scenario:신입시절 자꾸 엔터랑 esc누르면 프로그램이 꺼져서 암이 걸릴뻔함. 간단하게 오버라이딩으로 해결 할 수 있었음.


해당 클래스 클릭한뒤

PreTranslateMessage 함수 생성.



BOOL LensSpec::PreTranslateMessage(MSG* pMsg)

{

// 아래의 내용을 추가

 if(pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) return TRUE;


 return CDialog::PreTranslateMessage(pMsg);

}


'To be Developer > C,C++' 카테고리의 다른 글

[C++]상수화 constant  (0) 2017.01.18
[C++]List iter 사용법  (0) 2017.01.18
[MFC] MFC에서 디버깅시 콘솔창 띄우기  (0) 2017.01.18


scenario: 회사에서 mfc 프로그램을 만들던중 몇가지 기능을 확인하고자 system에 print 하고싶었다. 그래서 콘솔창을 띄우고싶엇다


solution:


//stdafx.h


#ifdef _DEBUG

#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")

#endif


'To be Developer > C,C++' 카테고리의 다른 글

[C++]상수화 constant  (0) 2017.01.18
[C++]List iter 사용법  (0) 2017.01.18
[MFC]엔터 또는 ESC입력시 프로그램 꺼짐 방지하는법  (0) 2017.01.18

+ Recent posts