1. 반드시 이니셜라이저를 통해서 초기화하자. 생성자에서 대입 연산으로 초기화 하는 것은 초기화가 아닌 대입이다(이미 객체의 생성자가 기본값이나 쓰레기값으로 초기화를 한 후 다시 초기화하는 꼴이된다)


2. 사용자 정의 자료형이 아닌 기본제공 자료형은 초기화가 될수도있고 안되어 있을 수도 있다.(int, char, double 등등)


객체를 구성하는 데이터의 초기화의 순서는 

1. 기본 클래스는 파생 클래스보다 먼저 초기화된다.

2. 클래스 데이터 멤버는 그들이 선언된 순서대로 초기화된다(이니셜라이저 초기화 순서는 상관없다)


정적 객체

1. 전역 객체

2. 네임스페이스 유효범위 안에서 정의된 객체

3. 클래스 안에서 static으로 선언된 객체

4. 함수 안에서 static으로 선언된 객체

5. 파일 유효범위에서 static으로 정의된 객체

이중 함수안에 있는 객체는 지역 정적 객체라 하고 밖에 있는 객체는 비지역 정적 객체라 한다.


번역단위

컴파일을 통해 하나의 목적 파일(Object File)을 만드는 바탕이 되는 소스 코드. 즉 #include 파일들까지 다 합쳐서 기계어로 번역하는 단위.


비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다.(순서는 랜덤, 즉 정해져있지 않다.)


두 비지역 정적 객체의 초기화 과정에서 연관관계가 있을 시, 초기화에 문제가 생긴다(누가먼저 초기화될지 모르니까)


해결책

싱글톤 패턴처럼 레퍼런스를 반환시켜주는 함수를 각각 만들고 적용시킨다.


정리

1. 기본제공 타입의 객체는 직접 초기화한다. 경우에 따라 저절로 되기도 하고 안되기도 하기 때문에


2. 생성자에서는, 데이터 멤버에 대한 대입문을 생성자 본문 내부에 넣는 방법으로 멤버를 초기화하지 말고 멤버 초기화 리스트(이니셜라이저)를 이용한다. 그리고 초기화 리스트에 데이터 멤버를 나열할 때는 클래스에 각 데이터 맴버가 선언된 순서와 똑같이 나열한다.


3. 여러 번역 단위에 있는 비지역 정적 객체들의 초기화 순서 문제는 피해서 설계해야 한다.

   함수를 이용해 비지역 정적 객체를 지역 정적 객체로 바꿔 사용한다.( 싱글톤패턴, 레퍼런스 반환      함수 )  





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

const 사용법  (0) 2015.01.28
Posted by 눈떠보니내무실
,

1. const 의 위치

void f1(const widget *pw)    //pw가 가리키는 값은 상수다.


void f2(widget const *pw)    //역시 pw가 가리키는 값은 상수다. 즉 위와 동일하다.


const vector<int>::iterator iter = vec.begin();    //iter는 T* const 처럼 동작한다.

*iter = 10;       //Ok. iter 가 가리키는 대상을 변경한다.

++iter;          //Error!, iter는 상수이기 때문에 변경이 불가능하다.


vector<int>::const_iterator iter = vec.begin    //iter는 const T*처럼 동작한다.

*iter = 10;       //Error!, iter 가 가리키는 대상은 상수다.

++iter;          //OK. iter 자체는 변수이므로 변경 가능.


2. 중복 코드 피하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class TextBlock
{
public:
    ...
    
    const char& operator[](size_t position) const //상수 객체를 위한 operator
    {
        return text[position];
    }
    
    char& operator[](size_t position) //비상수 객체를 위한 operator
                                                          //, 중복을 막기위해 상수버전을 호출한다.
    {
        return
          const_cast<char&>(           //반환 타입의 const를 날려버린다
             static_cast<const TextBlock&>(*this)[position]);  //static_cast를 통해 상수 operator를 
                                                             //불러온다.
            //*this는 TextBlock인데 이걸 const TextBlock로 형변환 함으로서 상수 객체를 위한 operator
            //를 불러올 수 있게 되는 것이다. 그냥 operator[] 를 부르면 자기자신을 계속부르는 무한루프에
            //걸리게 된다.
    }
    ......
};


1. const를 붙여 선언하면 컴파일러가 사용상의 에러를 잡아내는 데 도움을 준다. const는 어떤 유효범위에 있는 객체에도 붙을 수 있으며, 함수 매개변수 및 반환 타입에도 붙을 수 있으며, 멤버 함수에도 붙을 수 있다.


2. 컴파일러 쪽에서 보면 비트수준 상수성을 지켜야 하지만, 우리는 개념적인(논리적인) 상수성을 사용해서 프로그래밍 해야 한다.


3. 상수 멤버 및 비상수 멤버 함수가 기능적으로 서로 똑같게 구현되어 있을 경우에는 코드 중복을 피하는 것이 좋은데, 이때 비상수 버전이 상수 버전을 호출하도록 만들어야 코드의 낭비가 없어진다.(2번의 예처럼)









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

객체 초기화  (0) 2015.01.28
Posted by 눈떠보니내무실
,

예외처리

Programming/C & C++ 2014. 6. 9. 16:59

예외상황

프로그램 실행 중에 발생하는 문제의 상황을 의미한다.

문법적인 오류가 아닌 예외의 상황

즉 예외는 문법적 오류가 아닌, 프로그램 논리에 맞지 않는 오류를 뜻한다.

ex)

나이를 입력하라고 했는데 0보다 작은 값이 입력됨.

주민등록번호 13자리만 입력하라고 했는데 중간에 - 가 삽입됨.


예외처리

예외의 상황이 되었을 때 처리하는 방법. 문제의 해결이 아닌 순수한 처리이다.


if문을 이용해서 예외를 발견하고 처리하면, 예외처리 부분과 일반적인 프로그램의 흐름을 쉽게 구분할 수 없다.

if문은 일반적인 프로그램의 논리를 구현하는데 주로 사용된다.


문법

try~catch, throw

try

{

if(예외가 발생했다면)

throw expn; //예외가 발생되면 throw가 예외발생 했다고 알려주는 개념(expn은 정보)

}

//catch가 바로 붙어야 한다. 다른 문장이 올 수 없다.

catch(type expn)

{

//예외의 처리

}

try가 expn을 받아서 catch로 던진다!!(넘겨준다)


실행 예

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
void main(void)
{
    int num1, num2;
    cout << "두 개의 숫자 입력: ";
    cin >> num1 >> num2;
 
    try
    {
        if(num2 == 0)
            throw num2;
        
        cout << "나눗셈의 몫: " << num1/num2 << endl;
        cout << "나눗셈의 나머지: " << num1%num2 << endl;
    }
    catch(int expn)
    {
        cout << "제수는 " << expn<< "이 될 수 없습니다." << endl;
        cout << "프로그램을 다시 실행하세요" << endl;
    }
    cout << "end of main" << endl;
}
catch 블럭이 실행되면 예외가 처리된 것으로 간주된다.

예외와 연관이 있는 부분을 모두 하나의 try 블록으로 묶어야 한다!


예외가 처리되지 않으면, 예외가 발생한 함수를 호출한 영역으로 예외 데이터가(더불어 예외처리에 대한 책임까지) 전달된다.
예외처리 값은 처리가 될 때까지 넘어간다.
A->B->C->D(예외발생)  : main함수까지 넘어가고 main 함수에서 처리되지 못하면 종료되어 버린다.
예외를 처리하지 못하면 받은 함수던지 발생된 함수던지 간에 종료된다.

하나의 try블록에 다수의 catch블록이 존재할 수 있다.

전달되는 예외의 명시
int ThrowFunc(int num) throw(int, char)  //throw() <---아무런 예외도 발생하지 않는다고 명시
함수 내에서 예외상황의 발생으로 인해서 int형 예외 데이터와 char형 예외 데이터가 전달될 수 있음을 명시한 선언.
int, char 이외의 예외 데이터가 전달되면, terminate함수의 호출로 인해서 프로그램이 종료된다
프로그램의 종료는 대비하지 못한 예외상황의 처리를 알리는 의미로 받아들여진다.

객체를 예외 데이터로 던저주기(예외 객체, 예외 클래스)
예외객체 : 예외발생을 알리는데 사용되는 객체
예외클래스 : 예외객체의 생성을 위해 정의된 클래스





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

템플릿  (0) 2014.06.02
연산자 오버로딩  (0) 2014.06.02
멤버함수와 가상함수의 동작 원리  (0) 2014.06.02
static, 복사 생성자  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
Posted by 눈떠보니내무실
,

기본개념 정리

Windows 운영체제는 장치 독립적이다(어떤기기든 드라이버만 깔면 사용 가능)

윈도우는 Message 기반 구동 프로그램이고 Message 는 양의 정수값이다.


인스턴스(INSTANCE)

메모리에 로드되어 실행된 프로그램을 운영체제가 확인하기 위해 할당하는 양의 정수값을 말한다. 동일한 프로그램은 같은 인스턴스 값을 가지고 있다.


핸들(handle)

핸들은 운영체제의 자원을 사용하거나 윈도우를 생성할 때, 운영체제로부터 할당되는 양의 정수값이다. 고유 ID로 생각하면 이해하기 쉽다.

HWND, HDC, HPEN, HBRUSH, HBITMAP --> void* 형이다.

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

WinMain() 의 주된 역할 : 윈도우의 생성

윈도우 속성 설정 및 등록

윈도우 생성과 출력

메시지 루프(WinProc 호출)


WinProc() 의 주된 역할 : 메시지의 처리, 콜백(Call Back) 함수이다


API 프로그래밍 작성 순서 6가지

1단계: 윈도우 클래스 구조체

2단계: 윈도우 구조체 등록

3단계: 윈도우 생성

4단계: 윈도우 출력

5단계: 메시지 루프

6단계: 메시지 처리 함수인 WndProc() 의 작성

참고

http://nowcampus.tistory.com/ API 2장 참고













윈도우 창에 텍스트 띄우기 (wsprintf사용)

1. 글자가 들어갈 변수 선언 ( ex TCHAR lpOut[1024]; )

2. DC 얻어오기 (WM_PAINT 메시지 안에서는 BeginPaint로 , 이외의 공간에서는 GetDC로 얻어온다.

3. TextOut(DC, left좌표, top좌표, 저장공간, 들어올 문자의 길이) 로 출력 설정

4. wsprintf(저장공간, TEXT("출력할 서식문자: %d %f 등", 실제 출력할 값) 으로 출력




'Programming > API' 카테고리의 다른 글

Flag성 메시지와 함수  (0) 2014.06.06
API 2일차 도형 움직이기, 총알쏘기(06.05)  (0) 2014.06.06
API 1일차 개요(0602)  (0) 2014.06.05
Posted by 눈떠보니내무실
,

 

http://www.tipssoft.com/bulletin/tb.php/FAQ/632

 

참고

 

'Programming > API' 카테고리의 다른 글

API 개인 정리  (0) 2014.06.07
API 2일차 도형 움직이기, 총알쏘기(06.05)  (0) 2014.06.06
API 1일차 개요(0602)  (0) 2014.06.05
Posted by 눈떠보니내무실
,

주요 메소드 정리(인자값 순서대로 1, 2, 3, 4, ~~)

 WORD SetTimer(HWND hWnd, int nIDEvent,WORD wElapse,FARPROC lpTimerFunc)

->타이머를 생성하고 wElapse가 지정하는 간격으로 WM_TIMER메시지를 보낸다

1. WM_TIMER 메시지를 받을 윈도우의 핸들.

2. 타이머 번호. 타이머끼리의 구분을 위해 필요. KillTimer에 의한 타이머 해지시에도 필요.

3. WM_TIMER 메시지가 생성될 시간 간격을 1/1000초 단위로 지정한다.

4. NULL일 경우 WndProc으로 메시지 전달. 값이 지정되면 지정한 콜백함수로 전달된다.

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

BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase);

->지정된 구역의 화면을 지우고 다시 그린다.

1. 영역 설정 핸들. NULL일 경우 범위는 모든 윈도우가 된다(모든 윈도우?? -_-^).

2. 무효화할 영역. NULL이면 작업영역 전체가 무효화 된다.

3. 영역의 배경을 먼저 지울지 결정하는 곳. TRUE라면 먼저 지우고 출력되어 화면이 갱신되 된다.(즉 화면을 계속 지웠다 그리려면 TRUE, 아니면 FALSE값을 주면 된다.)

flag성 메시지 함수이다.

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

HDC GetDC(HWND hWnd);

->윈도우즈 환경에서 화면이나 프린터로 출력을 하려면 DC를 먼저 구해야 한다. DC를 구하는 일반적인 방법은 두 가지가 있는데 WM_PAINT 메시지내에서 DC를 얻을 때는 BeginPaint, EndPaint 함수쌍을 사용하며 이 메시지 이외의 코드에서 DC를 얻을 때는 GetDC, ReleaseDC 함수쌍을 사용한다. GetDC의 인수로 DC를 구하고자 하는 핸들을 주면 이 윈도우의 DC를 구해준다. 사용 후 ReleaseDC(hWnd, hdc) 로 해지해 주어야 한다.

1. 구하고자 하는 윈도우 핸들. NULL일 경우 전체 화면에 대한 DC가 구해진다. 

 

GetAsyncKeyState(VK_키타입)

GetAsyncKeyState() 함수와 GetKeyState() 함수는 키보드의 키가 눌렸는지를 체크하는 함수들이다.

GetAsyncKeyState() 함수는 비 동기(Asynchronism)로 처리한다. 즉, 호출된 시점에서 키 상태를 조사하여, 메시지 큐를 거치지 않고 바로 리턴을 해 주므로 키 입력을 바로 처리해 줄 수가 있다.

GetKeyState() 함수는 호출된 시점에서 메시지 큐를 거치며, 메시지 발생 후의 상태를 리턴하게 되므로, 키보드 메시지 처리 루틴내에서 사용해야 한다. 게임과 같이 키 입력에 바로 반응을 해 줘야 하는 프로그램에서는 GetAsyncKeyState()함수를 사용하는 편이 좋다.

1. 입력 키 타입(VK_LEFT, VK_UP 등등~)

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

GetMessage : 메시지 큐에서 메시지를 읽되 무한 대기하며 메시지를 무조건 큐에서 제거한다.

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

BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)

->GetMessage 함수와 마찬가지로 메시지 큐에서 메시지를 읽는다. 메시지의 범위를 줄 수 있는 기능도 GetMessage와 동일하다. 그러나 이 함수는 GetMessage와는 달리 읽은 메시지를 무조건 제거하지 않으며 큐가 비어 있을 경우 대기하지 않고 곧바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며 이런 특성은 백그라운드 작업에 적절하다.

메시지 큐에 메시지가 있으면 0이 아닌 값을 리턴하고 메시지가 없으면 0을 리턴한다.

lpMsg: 메시지를 받을 구조체이다.

hWnd: 메시지를 받을 윈도우이며 이 윈도우로 보내지는 메시지를 조사한다. 이 윈도우는 반드시 같은 스레드에 소속된 윈도우여야 하며 다른 스레드로 보내지는 메시지는 조사할 수 없다. 이 인수가 NULL이면 이 함수를 호출한 스레드로 전달된 모든 메시지를 조사한다.

wMsgFilterMin: 조사할 메시지의 최소값

wMsgFilterMax : 조사할 메시지의 최대값. 이 두 인수를 사용하면 일정한 범위에 속한 메시지만 조사할 수 있는데 이를 메시지 필터링이라고 한다. 예를 들어 키보드 관련 메시지만 조사하고 싶으면 WM_KEYFIRST, WM_KEYLAST로 범위를 지정할 수 있다. 두 인수가 모두 0이면 메시지 필터링을 하지 않으며 모든 메시지를 조사한다.

wRemoveMsg : 조사한 메시지를 처리할 방법을 지정하는 플래그의 조합이다.

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

플래그 설명

PM_NOREMOVE

메시지를 읽은 후 큐에서 메시지를 제거하지 않는다.

PM_REMOVE 메시지를 읽은 후 큐에서 메시지를 제거한다.
PM_NOYIELD 다른 스레드로 제어를 양보하지 않는다.
PM_QS_INPUT

디폴트로 이 함수는 모든 메시지를 다 처리하는데 이하의 플래그들을 지정하면 특정 메시지들만 처리하도록 할 수 있다. 이 플래그들은 98이상, 2000이상에서만 적용된다.

마우스나 키보드 등의 입력 메시지만 처리한다.

PM_QS_PAINT 그리기 메시지만 처리한다.
PM_QS_POSTMESSAGE 타이머나 핫키 메시지를 포함하여 붙여지는 메시지만 처리한다.
PM_QS_SENDMESSAGE 보내지는 메시지만 처리한다.

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

좀더 쉽게~

PM_NOREMOVE: 메시지가 있는지만 확인하고 그냥 빠져나온다
PM_REMOVE: 값이 없으면 else값을 만들어주는 옵션

REMOVE: 읽은 메세지를 자동으로 삭제해주는 인수값

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

DWORD GetTickCount(VOID)
=> OS부팅할 때부터 지나간 시간을 msec 단위로 돌려주는 함수이다.

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

BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu)

->작업 영역의 크기는 윈도우 크기에서 타이틀 바와 경계선, 메뉴, 스크롤 바 등의 영역을 제외한 영역이다. 일반적으로 MoveWindow, SetWindorPos 등의 함수로 윈도우 크기는 원하는대로 바꿀 수 있지만 작업 영역의 크기를 원하는대로 설정하는 방법은 없다. 작업 영역을 특정한 크기대로 설정하려면 이 함수로 원하는 윈도우 크기를 먼저 계산하고 MoveWindow 등의 함수로 윈도우 크기를 변경해야 한다.

이 함수는 윈도우의 스타일(타이틀 바의 유무, 타이틀 바의 높이, 경계선의 두께)와 메뉴의 존재 여부 등을 고려하여 작업 영역의 크기가 lpRect가 될 수 있는 윈도우 크기를 구해 lpRect로 리턴해 준다. 단 이 함수는 메뉴 바가 두 줄로 출력되어 있는 경우와 스크롤 바의 존재에 대해서는 정확한 계산을 해 주지 않는다. 만약 스크롤 바를 가지고 있다면 구해진 영역 크기에 스크롤바의 높이와 폭을 더해 주어야 한다.

 

lpRect:원하는 작업 영역의 사각 크기를 전달하면 이 인수로 조정된 윈도우 크기가 리턴된다.

dwStyle:윈도우의 스타일을 지정한다. WS_OVERLAPPED 스타일은 지정할 수 없다.

bMenu:메뉴가 있으면 TRUE를 전달하고 그렇지 않으면 FALSE를 전달한다.

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

 

 

 주요 Message 정리

WM_CREATE

윈도우 생성 후 화면에 출력되기 전에 보내지며 윈도우에 관련된 초기화 작업에 대한 내용이 처리된다. flag 메시지이다

 

WM_KEYDOWN

키보드 눌림에 따른 메시지를 받는다.

 

VK_ESCAPE

ESC 버튼에 관한 메시지를 받는다.

 

VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN

키보드의 좌우상하 입력을 받는다.

 

VK_SPACE

스페이스 버튼을 입력받는다.

 

WM_DESTROY

DestroyWindow 함수가 반환하는 DESTROY 메시지를 받는다. 윈도우가 파괴될 때 메시지를 받는다.

 

WM_TIMER (flag 메시지이다)

SetTimer 함수로 타이머를 설치했을 경우 지정한 시간 간격으로 이 메시지가 반복적으로 큐에 붙여진다. 주기적으로 어떤 작업을 반복해야 한다면 타이머를 설치하고 이 메시지에서 작업을 처리하도록 한다. 두 개 이상의 타이머가 설치되어 있을 경우 각각의 타이머는 정해진 시간 간격으로 이 메시지를 큐에 붙이며 WM_TIMER에서는 wParam으로 어떤 타이머에 의해 이 메시지가 발생했는지 조사한다.

 

 

 

기타 정리

 Message.msg : 메시지의 ID번호를 가져오거나 설정한다.

 

 extern : 전역변수 앞에 선언하면 모든 프로젝트 공간에서 사용가능하다. 은닉화를 파괴 하는 개념이기 때문에 꼭 필요할때만(다른파일에서 핸들값 사용하기) 사용해야 한다.

 

int WINCX, int WINCY : 여기서 C는 size의 헝가리안 표기법이다.

 

 

 

 

 

'Programming > API' 카테고리의 다른 글

API 개인 정리  (0) 2014.06.07
Flag성 메시지와 함수  (0) 2014.06.06
API 1일차 개요(0602)  (0) 2014.06.05
Posted by 눈떠보니내무실
,

API = Application Programming Interface

 

용어

__stdcall //(함수가 가변인자를 가질 수 없다) 제공되는 함수 그대로 호출해서 써야한다

call back //API 함수 호출 규약, 시스템이 특정 상황인지를 수시로 체크하다 그 특정 상황이 되면 지정된 함수를 호출하게 됨

 

메시지 처리 ( API는 메시지 처리 방식이다!!)

Message Queue(이벤트->Message Queue 로 들어간다)

 A(출구)

 B

 B

 A

 C

 E(메시지들어옴)

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

OS를 거쳐 ----->A에 해당하는 곳으로 메시지 전달.(OS가 전달한다)

OS를 거쳐 ----->B에 해당하는 곳으로 메시지 전달.(OS가 전달한다)

 

모든 행동(키보드, 클릭 등등 메시지를 전달한다)
->하드웨어 이벤트로 인한 메시지 발생.

키보드-------->하드웨어 이벤트--------->OS가 감지------->메시지 처리------------>프로그램(처리)
처리 후 역순으로 메시지를 전달한다.

 

GetMessage 는 Message Queue가 내부에 삽입되어 있다.

while (GetMessage(&msg, NULL, 0, 0))  //quit 메시지가 들어오면 종료
{
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     {
          TranslateMessage(&msg); //어떤 메시지가 들어오면 아스키코드로 치환
          DispatchMessage(&msg);  //메시지 처리 WndProc 호출한다.
     }
}

 

각 자료형 설명

handle : 핸들, 정수값, 각종 프로그램의 고유 식별 번호(각 프로그램마다 가지고 있다)
WPARAM : 키보드 메시지
LPARAM : 마우스 메시지
DWORD  : time
POINT  : 마우스의 좌표를 저장하기 위한 구조체

hInstance(창의 식별번호를 의미한다고 보면 된다)

 

아스키코드 치환 이유
API는 다국적을 지원하기 때문에(유니코드)

유니코드화 
일반상수 앞에 L을 넣어준다.
_T(), TEXT() 등을 넣어준다.

 

메시지 driven방식이란??

윈도우 프로그램의 기본 동작 방식이다.
즉 사용자(프로그램을 사용하는 사람)이 어떤 행동(즉, 마우스를 클릭했다거나 키보드를 눌렀을 경우)을 했을 때 윈도우 관리자로 사용자의 행동이 메시지 형태로 넘어간다.
그럼 윈도우 관리자는 그 메시지를 그 사용자가 행동한 윈도우 메시지 큐에 넣어주게 된다.
메시지 드라이븐(혹은 처리)방식이란
이렇듯 윈도우 관리자로 부터 메시지를 받았을 때 자신이 원하는 코딩을 해 주는 방식입니다. 직접적인 코딩이 필요없을 경우 다시 윈도우 관리자로 넘기게 된다.

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

실질적인 메시지 처리는 이 함수에서 한다. 핸들과 메시지, 키보드 마우스 값을 인자로 받는다.

 

그리기의 개념
그리기의 개념은 굉장히 빠르게 다른 그림들을 출력해서 움직이도록 보이는 것이다. 전에 있던 그림

은 지운다.
hdc :그림을 그리는 도화지라고 생각하면 이해하기 쉬움

x1 : LEFT
y1 : TOP
x2 : RIGHT
y2 : BOTTOM

 

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

그림 그리기

case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);

  //이곳에 그리는 함수를 넣는다

  EndPaint(hWnd, &ps);

 

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

Esc로 창 파괴하기

case WM_KEYDOWN:
   switch(wParam)
   {
        case VK_ESCAPE:
        DestroyWindow(hWnd);
        break;
   }
   break;

 

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

메뉴 없애기

wcex.lpszMenuName = NULL;  //NULL이면 메뉴라인이 없어진다.

 

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

커서 바꾸기

wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);

 

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

배경색 바꾸기

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

뒤에 +1 정수값을 바꿔주면 됨

 

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

 

 

 

 

 

 



 

 

 

 

'Programming > API' 카테고리의 다른 글

API 개인 정리  (0) 2014.06.07
Flag성 메시지와 함수  (0) 2014.06.06
API 2일차 도형 움직이기, 총알쏘기(06.05)  (0) 2014.06.06
Posted by 눈떠보니내무실
,

Map

Programming/STL 2014. 6. 2. 10:35

map

map은 노드기반 컨테이너다. 양방향 반복자를 사용하며 []가 연산자 오버로딩 되어있다. 삽입이 느리고 검색과 정렬이 빠르다.(타일과 지형은 벡터로, 이미지는 map으로)

 

한번에 2개의 값을 집어넣는다( key, value)

key : 분류 기준, 정렬의 기준이 된다.

value : 직접적인 데이터이다.

 

map<키, 벨류> m_map;

m_map.insert(pair<키, 벨류>(키값, 벨류값)); //pair는 반드시 생성해줘야 하는 임시객체

 

iter->first : 키값    iter->second : 벨류값

 

키값이 동일하다면?

map : 중복키값 비허용

multimap : 중복키값 허용

 

사용 예

m_map.insert(pair<int,string>(5,"ABC"));

m_map.insert(make_pair(5, "ABC")); //make_pair는 직접 만든것

insert 사용시 키값이 중복된다면 처음것이 남아있다.

대입 사용시 키값이 동일하다면 나중것이 남아있다.

 

iter = m_map.find(n)  //특정값을 찾을 때 사용한다.

 

map의 3번째 인자(정렬)    기본 less(오름차순) , 내림차순은 greater

 

multimap은 = 이 되지 않는다. 키값이 중복 가능하다.

'Programming > STL' 카테고리의 다른 글

List  (0) 2014.06.02
vector  (0) 2014.06.02
반복자, 조건자  (0) 2014.06.02
STL 개요  (0) 2014.06.02
Posted by 눈떠보니내무실
,

List

Programming/STL 2014. 6. 2. 10:02

리스트

push_front, pop_front, push_back, pop_back 모두 사용 가능

 

list<int> lt;

 

lt.reverse() : lt의 순차열을 뒤집는다.

lt.splice(p,lt2) : p가 가리키는 위치에 lt2의 모든 원소를 잘라 붙인다.

lt.splice(p,lt2,q) : p가 가리키는 위치에 lt2의 q가 가리키는 원소를 잘라 붙인다.

 

list는 sort를 기본 제공한다.

lt.sort(조건자)        기본적으로 오름차순으로 되어있다.

'Programming > STL' 카테고리의 다른 글

Map  (0) 2014.06.02
vector  (0) 2014.06.02
반복자, 조건자  (0) 2014.06.02
STL 개요  (0) 2014.06.02
Posted by 눈떠보니내무실
,

vector

Programming/STL 2014. 6. 2. 09:34

vector

사용가능한 컨테이너함수: push_back(), pop_back();

벡터의 문제점: 메모리의 재할당, 느리다

 

vector<int> vec(3); //0으로 초기화된 벡터 3개를 미리 선언

vec.clear();   //vec안의 원소들을 모두 지움

vec.empty(); //비어있다면 true를 반환함

 

자주 사용되는 것들

vector<int>::iterator p;

vector<int>::iterator q;

 

vector v(n) : v는 기본값으로 초기화된 n개의 원소를 갖는다.

vector v(n,x) : v는 x값으로 초기화된 n개의 원소를 갖는다.

vector v(v2) : v는 v2컨터이너의 복사본이다.

p = v.begin() : p는 v의 첫 원소를 가리키는 반복자이다.

p = v.end() : p는 v의 끝을 표식하는 반복자이다.

v.clear() : v의 모든 원소를 제거한다.

v.empty() : v가 비었는지 조사한다. 비었으면 true를 반환한다.

q = v.erase(p) : p가 가리키는 원소를 제거한다. q는 다음 원소를 가리킨다.

q = v.erase(b,e) : 반복자구간[b,e)의 모든 원소제거, q는 다음 원소를 가리킨다

q = v.insert(p,x) : p가 가리키는 위치에 x값을 삽입. q는 삽입한 원소를 가리킴

v.push_back(x) : v의 끝에 x값을 추가한다.

v.pop_back() : v의 마지막 원소를 제거한다.

v.size() : v원소 개수의 반환

v[i] : v의 i번째 원소를 참조한다.

v.front() : 첫 원소 참조

v.back() : 마지막 원소 참조

v.assign(n,x) : n개의 원소에 x값을 할당한다.

v.reserve(n) : n공간만큼 미리 만들어놓고 쓴다(n만큼은 재할당이 일어나지 않는다)

v.resize(n) : n만큼 사이즈 변경, v(3)같이 초기화된 경우 3->n으로

 

임시객체와 swap을 이용해 지우는 방식

vector<int>().swap(v)    //swap은 같은 컨테이너끼리, 같은 자료형끼리 가능

 

 

 

 

 

 

 

'Programming > STL' 카테고리의 다른 글

Map  (0) 2014.06.02
List  (0) 2014.06.02
반복자, 조건자  (0) 2014.06.02
STL 개요  (0) 2014.06.02
Posted by 눈떠보니내무실
,

iterator 선언 예

vector<int>::iterator iter;         iter = m_iVec.begin();

 

반복자의 종류

1. 입력 반복자 : 파일, 원소를 한번만 읽을 수 있다.

2. 출력 반복자 : 값을 넣을 수 있는 반복자.

3. 순방향 반복자 : ++ 이 연산자 오버로딩 되어있다.

4. 양방향 반복자 : ++, --가 연산자 오버로딩 되어있다.

5. 임의접근 반복자 : 배열기반 컨테이너만 사용 가능하다. +, -, ++, --, [] 가 연산자

                              오버로딩 되어있다.

 

조건자

count_if(begin, end) : 구간 내 데이터 개수 반환

조건자 - 단항 조건자

           - 이항 조건자

 

이항 조건자

sort(begin(), end() ,greater<int>());  //less<자료형>()는 오름차순, greater는 내림차순

 

'Programming > STL' 카테고리의 다른 글

Map  (0) 2014.06.02
List  (0) 2014.06.02
vector  (0) 2014.06.02
STL 개요  (0) 2014.06.02
Posted by 눈떠보니내무실
,

STL 개요

Programming/STL 2014. 6. 2. 08:31

STL의 사용 목적

-효율성, 재사용성, 확장성

 

STL의 컨터이너 종류

1.표준 시퀀스 컨테이너(vector, list, deque) 시퀀스의 뜻은 순차열이다.

2.표준 연관 컨테이너(트리구조) (set,multiset,map,multimap)

3.표준 배열기반 컨테이너(vector, deque)

4.표준 노드기반 컨테이너(나머지 다~~)

5.컨테이너 어댑터(어댑터 컨테이너) (Queue, Stack, 우선순위Queue를 지원하는 것)

 

예외: 근사 컨테이너: string (템플릿으로서 올바른 것인가??)

 

STL은 기본지원을 하지만 외부참조 파일이다.

 

시퀀스 컨테이너 함수

push_back() : 맨 뒤에 추가한다.

push_front() : 맨 앞에 추가한다.

pop_back()  : 맨 뒤에서 뺀다(삭제한다).

pop_front()  : 맨 앞에서 뺀다(삭제한다).

 

[]인덱스 연산자를 사용할 수 있는 것: vector, deque, map

.size() //원소의 개수를 구하는 함수. string은 문자의 길이를 구함.

'Programming > STL' 카테고리의 다른 글

Map  (0) 2014.06.02
List  (0) 2014.06.02
vector  (0) 2014.06.02
반복자, 조건자  (0) 2014.06.02
Posted by 눈떠보니내무실
,

템플릿

Programming/C & C++ 2014. 6. 2. 08:14

템플릿(템플릿은 틀이다!!)

함수 템플릿과 템플릿 함수의 구분

 

함수 템플릿

template<typename T>   //typename 대신 class를 사용할 수 있다.

T Add(T num1, T num2)    여기서 class는 일종의 부류 라는 뜻이다.

{

return num1 + num2;

}

 

void main(void)

{

Add<int> (3, 4);  //이 함수가 호출되었을 때

}

 

위에 함수 템플릿을 참고하여 컴파일러가

 

템플릿함수

int Add<int> (int num1, int num2)

{

return num1 + num2;

}

를 만들어 낸다.

한번 만든 함수는 다시 만들지 않는다.

 

인자가 2개인 경우

template<class T1, class T2>

void Render(double)

{

cout << T1 << "  " << T2 << endl;

}

이 경우 호출할 때 T1과 T2의 타입을 명시해줘야 한다.

ex) Render<char, double>(68, 1.2);

 

함수 템플릿의 특수화

내가 원하는 함수의 형태를 찍어내지 않고 미리 정의해놓은 함수를 호출하게 함

template<>   <---- 이 선언을 추가해준다.

원하는 함수

 

클래스 템플릿

클래스 템플릿이 정의되어 있을 때

Point<int> pos(2,4);  <int> <--- 이처럼 따로 명시해 주어야한다. 이는 약속이다.

 

클래스 템플릿의 선언과 정의의 분리

PointTemplate.h

1
2
3
4
5
6
7
8
9
10
11
#pragma once
 
template <class T>
class Point
{
private:
    T xpos, ypos;
public:
    Point(T x=0, T y=0);
    void ShowPosition() const;
};

PointTemplate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "PointTemplate.h"
using namespace std;
 
template <class T>
Point<T>::Point(T x, T y) : xpos(x), ypos(y)
{}
 
template <class T>
void Point<T>::ShowPosition() const
{
    cout << "[" << xpos << ", " << ypos << "]" << endl;
}

PointTemplateMain.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include "PointTemplate.h"
#include "PointTemplate.cpp"
using namespace std;
 
void main(void)
{
    Point<int> pos1(3,4);
    pos1.ShowPosition();
 
    Point<double> pos2(2.4, 3.6);
    pos2.ShowPosition();
 
    Point<char>    pos3('P''F');
    pos3.ShowPosition();
}

1. 헤더파일과 cpp파일 모두에 template<typename T>를 명시해줘야 한다.

2. SimpleTemplate<T>::SimpleFunc();   <T> <--이처럼 명시해줘야 한다.

3. 하나의 파일에 템플릿의 선언과 정의부를 모두 넣어줘야 한다.

3-1. 헤더와 cpp파일 모두 include 한다.(여기선 PointTemplateMain.cpp)

3-2. 헤더에 정의부까지 넣어준다.


클래스 템플릿의 특수화

template<>

class SoSimple<int>

{

public:

int SimpleFunc(int num) { ....}

};


클래스 템플릿의 부분 특수화

template<typename T1>

class MySimple<T1, int> { ....}


템플릿 인자

template <typename T, int len>

class SimpleArray

{

private:

T arr[len];

public:

T&  operator[] (int idx)

{

return arr[idx];

}

};

라는 클래스가 있을 때

SimpleArray<int, 5> i5arr;

SimpleArray<double, 7> d7arr; 처럼 객체를 생성하고 5와 7은 상수화된다.


템플릿 매개변수의 티폴트 값 지정하기

template <typename T=int, int len=7> //T에 int가, len에 7이 디폴트 값으로 지정됨


static 지역변수 역시 각 템플릿이 찍어내는 함수별로 존재하게 된다. 


static 멤버변수 초기화의 특수화

template<>

long SimpleStaticMem<long>::mem=5;



 

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

예외처리  (0) 2014.06.09
연산자 오버로딩  (0) 2014.06.02
멤버함수와 가상함수의 동작 원리  (0) 2014.06.02
static, 복사 생성자  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
Posted by 눈떠보니내무실
,

연산자 자체가 함수의 이름이 되는 문법이다.

사용자 자료형만 정의가 가능하다(기본자료형 x 고유기능이 있기때문에)

 

Point p1, p2;

p1 + p2    //원래는 불가능

+ : c++컴파일러와의 약속. operator+ 함수가 호출되는 것으로 간주함

operator+가 멤버함수일 때

p1.operator+(p2);  <--이렇게 호출된다.

operator+가 전역함수일 때

operator+(p1, p2);

전역으로 정의할 때 friend를 사용한다.

 

연산자 오버로딩의 뜻

fct(), fct(int a)... 매개변수에 따라 다른 기능의 함수가 되는 오버로딩

+

3 + 4, p1+p2... 피연산자에 따라 기능이 바뀌는 +.. 오버로딩이라는 이름을 붙여주었다.

 

연산자 오버로딩은 약속이다!!

함수호출의 경로를 하나 더 마련해 준 것이다.

멤버함수의 형태로만 오버로딩이 가능하다.

전역함수 형태는 데이터 종속성이 없다.

접근할 객체를 마련해놓고 함수호출을 하도록 제약을 걸어놓은 것이다.

 

연산자 오버로딩은 매개변수의 디폴트 값 설정이 불가능하다.

기본자료형은 operator+(n1, n2) 형태로 오버로딩 된다.

 

 

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

예외처리  (0) 2014.06.09
템플릿  (0) 2014.06.02
멤버함수와 가상함수의 동작 원리  (0) 2014.06.02
static, 복사 생성자  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
Posted by 눈떠보니내무실
,

함수는 주소값으로 접근하는데 virtual 선언 시 가상함수 테이블이 만들어져서 함수의 주소가 올라간다. (테이블은 가상함수가 어디있는지 알려주는 역할을 한다)

가상함수 포인터가 내부적으로 존재한다.

가상함수 테이블은 최소 4byte이다.

 

클래스별로 v_table은 하나씩 존재한다.

 

가상함수 테이블은 c++의 단점이다. (속도의 저하)

 

virtual을 붙였을 때 발생되는 2가지

1. 가상함수 테이블

2. 가상함수 포인터: 가상함수가 하나라도 존재하면 4byte의 가상 함수 포인터가 할당된다. 이것은 약점이다!!

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

템플릿  (0) 2014.06.02
연산자 오버로딩  (0) 2014.06.02
static, 복사 생성자  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
상속과 가상함수(기본개념)  (0) 2014.06.02
Posted by 눈떠보니내무실
,

static

전역변수화 되어 데이터 영역에 들어간다.

클래스 안에서 static 변수 (class 변수)

->생성자 초기화 불가능, 이니셜라이저 초기화 불가능(class 내에서 초기화 불가능)

->static 변수는 멤버변수와 할당 시점이 다르다.

 

class 밖에서 초기화 방법

자료형 클래스이름::변수이름 = 값;(private의 유무와 상관 없는 문법이다.)

 

데이터 영역의 특징

int CObj::m_iB;  <-BSS에서 0으로 초기화 후 데이터로 올라간다.

int CObj::m_ib = 100;  <-바로 데이터 영역으로 올라간다.

 

복사 생성자

객체를 복사할 때 생기는 생성자

복사생성자 호출 시점

1. 먼저 만든 객체가 나중에 만든 객체의 인자값으로 들어가 생성되는 경우

2. 매개변수 복사

3. 값 반환시 임시객체에 복사한다. 이때 호출된다.

 

얕은 복사(shallow copy)

값과 값이 단순히 복사되는 것

깊은 복사(deep copy)

생성자에서 동적할당을 하고 소멸자에서 해제할 때 필요

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

연산자 오버로딩  (0) 2014.06.02
멤버함수와 가상함수의 동작 원리  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
상속과 가상함수(기본개념)  (0) 2014.06.02
레퍼런스(참조자)  (0) 2014.06.02
Posted by 눈떠보니내무실
,

함수 오버라이딩

기초(부모) 클래스에서 정의된 함수의 이름과 동일한 이름을 유도(자식)클래스에서 기능을 재설정하여 선언하는 것. 함수의 이름이 판단기준이다. 매개변수의 자료형 및 개수가 다르면 이는 함수 오버로딩이 된다. 오버로딩은 상속관계 에서도 구성이 될 수 있다.

 

virtual 선언

선언하면 실제로 가리키는 객체의 가장 마지막에 오버라이딩 된 함수가 호출된다. 

vurtual fct() 했을 때

A* ptr = new A1  //A1의 fct 호출

A* ptr = new B2  //B2의 fct 호출

A* ptr = new C3  //C3의 fct 호출

 

static바인딩, 정적 바인딩

CObj* pObj = new CPlayer; 에서

부모의 Render() 를 불러오는 두가지 방법

1. Player의 Render() 안에 CObj::Render() 넣기

2. pObj->CObj::Render()   :: <- 스코프 연산자

 

오버라이딩을 위해 아무 기능이 없는 함수를 부모 클래스에 만들어 주기도 한다.

이때 몸체 부분을 생략할 수 있는데 다음과 같이 선언한다.

virtual int GetPay() const = 0;

이를 순수 가상함수라 한다.

 

순수 가상함수의 특징

ex) Employee 라는 부모 클래스에 순수가상함수를 선언해 놓으면 Employee클래스로는 객체 생성이 불가능하다.

객체생성이 불가능한 이유

순수 가상함수 부분에서 메모리 할당이 되지 않기 때문에(껍데기만 정의되어 있으므로)

하나 이상 순수가상함수를 가지고 있는 클래스를 추상클래스 라고 한다.

추상클래스는 자료형 선언시 포인터만 선언할 수 있다.

 

가상 소멸자(이름이 다른 함수가 오버라이딩 되는 특수한 예)

상속 관계에 있고 소멸자에서 동적할당을 해제하며 다형성 관계일때,

A1* ptr = new C1;

delete ptr; //A1 클래스의 소멸자만 호출된다.(자식소멸자는 호출x 메모리 누수 생김)

따라서 소멸자에서 virtual을 붙여줘야 한다.

virtual 소멸자가 실행되면 C1객체의 소멸자를 호출하고 차례대로 위로 올라오면서 부모 클래스의 소멸자까지 호출시키게 된다.(자식 객체는 자식소멸자->부모소멸자 순으로 해지되기 때문에 가능)

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

멤버함수와 가상함수의 동작 원리  (0) 2014.06.02
static, 복사 생성자  (0) 2014.06.02
상속과 가상함수(기본개념)  (0) 2014.06.02
레퍼런스(참조자)  (0) 2014.06.02
const 사용, 이니셜라이저  (0) 2014.06.02
Posted by 눈떠보니내무실
,

상속

부모 클래스를 자식클래스가 물려받아 부모의 멤버변수를 자식클래스에서 사용할 수 있다.(protected 선언이 되어있으면 자식클래스에서 맴버변수에 바로 접근도 가능하다)

 

상속의 이유

상속은 연관된 일련의 클래스들에 대해 공통의 규약을 적용할 수 있게 해준다.

 

자식 클래스의 생성 단계

1. 메모리 할당

2. 부모 생성자 호출

3. 자식 생성자 호출

 

자식 클래스의 소멸 단계

1. 자식 소멸자 호출

2. 부모 소멸자 호출

3. 메모리 반환

 

상속의 조건

Is a 관계

has a 관계

 

업케스팅: 접근은 부모, 할당은 자식

다운케스팅: 부모의 자료형을 강제로 자식의 자료형으로 만든 후 자식의 함수를 호출한다.

 

가상함수

먼저 익혀야 할 개념

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base
{
public:
    void BaseFunc(void)    { cout << "base" << endl; }
};
 
class Derived : public Base
{
public
 
    void DerivedFunc(void) { cout << "derived" << endl; }
};
 
void main(void)
{
    Base* bptr = new Derived;
    bptr->BaseFunc(); //bptr->DerivedFunc() 에러발생
}

 

 결과

 

이유: 부모 클래스 객체는 자식 클래스에서 자기가 가지고 있는것만 가리킬 수 있다.

 

위 상황에서

Base* bptr = new Derived;   //컴파일 성공

Derived *dptr = bptr; //컴파일 에러

이유

Derived 클래스의 모든 데이터를 Base는 가지고 있지 못하다. 따라서 Base는 모두 가리킬 수 없으므로 에러가 발생한다.

 

Derived* dptr = new Derived;    //컴파일 성공

Base* bptr = dptr;    //컴파일 성공

이유

dptr은 Derived형 포인터 변수이다. Derived는 Base를 상속받고 Base의 모든것을 가리킬 수 있기 때문에 가능하다.

 

결론

컴파일러는 실제 무엇을 가리키는지는 관심없다. 오직 포인터 변수의 type형 만을 가지고 판단한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class First
{
public:
    void FirstFunc(void) { cout << "FirstFunc" << endl; }
};
 
class Second : public First
{
public:
    void SecondFunc(void) { cout << "SecondFunc" << endl; }
};
 
class Third : public Second
{
public:
    void ThirdFunc(void) { cout << "ThirdFunc" << endl; }
};
 
void main(void)
{
    Third* tptr = new Third;
    Second* sptr = tptr;
    First* fptr = sptr;
 
    tptr->FirstFunc();
    tptr->SecondFunc();
    tptr->ThirdFunc();
 
    sptr->FirstFunc();
    sptr->SecondFunc();
    //sptr->ThirdFunc();    //에러
 
    fptr->FirstFunc();
    //fptr->SecondFunc();    //에러
    //fptr->ThirdFunc();    //에러
}

 

실제 가리키는 것이 무엇이든 간에 포인터 타입에 따라 가리키는 범위가 결정된다.

 

 

 

 

 

 

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

static, 복사 생성자  (0) 2014.06.02
virtual 키워드와 다형성  (0) 2014.06.02
레퍼런스(참조자)  (0) 2014.06.02
const 사용, 이니셜라이저  (0) 2014.06.02
this 포인터, 전방선언  (0) 2014.06.02
Posted by 눈떠보니내무실
,

&(레퍼런스, 참조자)는 포인터를 대용하기 위해 나온 개념이다.

 

 

int num = 10;

int &ref = num; 일 때

ref 는 num과 같은 변수가 된다(참조한다)

 

int &ref( int &a ) { return a; } 으로 정의된 경우

int temp = ref(num1);     //(가능)

int &temp = ref(num1);  //(가능)

 

int ref(int &a)  { return a; } 으로 정의된 경우

int temp = ref(num1);     //(가능)

int &temp = ref(num1);  //(불가능)

 

const int num = 20;

const int &ref = num; //(가능)

const int &ref = 50 //(가능) -> 50이 임시변수에 저장되기 때문에 가능하다.

 

const의 뜻: 변수를 상수화시킴. 즉 상수화된 변수를 만든다.

 

int num = 20 + 30;  (여기서 20과 30을 리터럴 상수라 한다. 리터럴 상수는 임시적으로 존재하는 값으로 다음행으로 넘어가면 존재하지 않는다.)

 

void HappyFunc(const int &ref) { }

함수 HappyFunc 내에서 참조자 ref를 이용한 값의 변경은 허용하지 않는다.

 

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

virtual 키워드와 다형성  (0) 2014.06.02
상속과 가상함수(기본개념)  (0) 2014.06.02
const 사용, 이니셜라이저  (0) 2014.06.02
this 포인터, 전방선언  (0) 2014.06.02
class 기본개념  (0) 2014.06.02
Posted by 눈떠보니내무실
,

int a = 10;

const int*  p;    *p = 10; (불가능)     p = &a; (가능)

int* const  p;    *p = 10; (가능)        p = &a; (불가능)

const int* const  p;    *p = 10; (불가능)        p = &a; (불가능)


const가 선언된 함수내에서는 멤버변수의 조작도 불가능하고 const가 선언된 함수만 호출할 수 있다.(데이터 변경의 여지를 차단하기 위해서)


class A

{

private:

int m_iA;

const int m_iB;

public:

A()

{

m_iA = 0; (가능)

m_iB = 0; (불가능) //객체 생성시 공간이 먼저 할당되고 그곳에 쓰레기값이 들어

                             있기 때문에 대입이 되지 않는다.

}

};


A() : m_iB(0) //멤버상수 초기화를 위한 문법. 멤버변수 초기화도 가능함

{

m_iA = 0;

}


멤버상수는 생성자마다 모두 지정해줘야 한다.

이니셜라이저는 블록단위(배열) 데이터 초기화가 불가능하다.

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

상속과 가상함수(기본개념)  (0) 2014.06.02
레퍼런스(참조자)  (0) 2014.06.02
this 포인터, 전방선언  (0) 2014.06.02
class 기본개념  (0) 2014.06.02
파일 입출력, 분할 컴파일  (0) 2014.06.02
Posted by 눈떠보니내무실
,