2010년/5월

5월10일 c++(레퍼런스(참조),생성자) API(DC 그림,메시지박스)

뽀얀햄스터 2010. 5. 10. 11:48
c++에서는 값 전달에서
특히 참조(주소) 전달에서  저런 식으로 가능하다.
모양은 포인터랑 비슷하다 하지만 사용방법은
r.input_car()로 .연산자를 사용해야한다....

alias(별칭)라고 한다.
즉 NewCar의 다른 별칭 별명을 r이라고 볼수 있다.




다음 심볼 테이블을 보자

NewCar와  r은 주소랑 type이 같다 단 이름만 틀리다. 그래서 r과 NewCar를 같은것이다.

다음 r과 NewCar를  알아보는소스이다.


그 결과값



보다시피 r과 NewCar의 크기가 같다. 그리고 주소까지 같다. 이는 r이 NewCar처럼 쓸수있다. 포인터보다 장점이라고한다면 포인터는 4바이트를 할당받아서 공간을 받고 다시 주소가지만 이런 참조전달은 그냥 바로 사용이 가능하다.

하지만 참조전달의 단점도 있다. 바로  초기화 과정이다. 위에 약간 수정되지 않은 부분이 있다.

car &r=NewCar; 의 형태이다 이렇게 초기화를 해야한다. 하지만
car &r;
r=NewCar;를 할경우 초기화되지않은 컴파일 에러 메시지를 띄운다. 그리고

car NewCar;
car NewCar2;

car &r=NewCar;
r=NewCar2;
할경우 NewCar=NewCar2랑 마찬가지이기때문에 NewCar에 값이 들어간후 다시 NewCar2로 인해 쓰레기 값이 들어가기때문에 제일 처음에 초기화 이외에는 어떻게 보면 쓸모가 없다.
하지만 참조전달(레퍼런스)를 아주 큰 장점이 있다.
바로 그것은 함수를 사용할때 이다 함수가 양이 많아지면 포인터로 사용하지만 참조전달을 사용할경우
함수를 마음대로 가져 놀수 있다. 아주 좋음~

==생성자(Constructor) ==>
C++에서 객체가생성할때 딱한번 호출되는것을 생성자라고 한다. (함수)
생성자의 특징은 첫번째 함수와 비슷하게 생겼지만 반환형이 없다.
그리고 두번째 특징은 클래스와 이름이 같다.

저 앞에
car()
{
   cout<<"생성자없음"<<endl;
}
바로 car() 이것이 생성자이다 그리고 반환형은 역시 없고  생성자는 객체가 생성될때 딱한번 호출이라고 한다. 우리가 부르지 않았지만 자동으로 호출이 된다.
 








다음 결과 값을 보자

바로 저값은 main.c에서  car NewCar;로 인해
NewCar라는 객체가 한번 생성되면 바로 생성자가 한번 실행되었다.
그래서 만약
car NewCar,NewCar2;를 할경우
생성자 생성
생성자 생성

이렇게 두번 생성자가 실행되는것을 알수 있다.
그럼 저 생성자에  다음과 같이 넣었다.




-결과값-





그리고 생성자의 반대로는 소멸자가 있다.  소멸자는 생성자와 반대로 객체가 종료될때 실행시켜주는것이다 하지만 만약 객체가 2개 있을경우 어떻게 될까?
이문제는간단하다. 생성자가 생성과정에서 순서대로 생성된다. 하지만 소멸 과정은 마지막에 생성한것부터 소멸한다.
처음에 쏘나타를 생성자로 입력했다.

두번째로 티코를 입력했다.

결과값은 티코가 출력되고 쏘나타가 출력되었다.


생성자는 모양을 바꿀수 있다. 바로 car(int k)같은 경우인데
car(int k)
{
  cout<<k<<endl;
}
인수가 생겨 버렸다. 하지만 인수가 생기면 그만큼 생성될때
car NewCar;로 되지만 car NewCar(7) 객체가 인수를 가지면 바로 출력
NewCar(7)이 생성자로 7이 찍혀버린다.
=======================================================================
=======================================================================
DC(Device Context)

문자열 출력 
GetDC(hWnd);
ReleaseDC(hWnd,hdc);
그림 그리기 집, 정사각형 네모
#include<windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
LPCTSTR lpszClass=TEXT("메시지박스 실험");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.
void Line(HDC hdc, int x1, int y1,int x2, int y2)
{
 MoveToEx(hdc,x1,y1,NULL);
 LineTo(hdc,x2,y2);
}
void MyTextOut(HDC hdc,int x,int y,LPCTSTR Text) //TextOut함수같은경우는 문자열의길이를 넘겨야한다 하지만
            //그수고를 덜기위해서 만든 함수
{
 TextOut(hdc,x,y,Text,lstrlen(Text));
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
 g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

 WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
 WndClass.cbWndExtra=0;//않을 때는 0으로 지정한다.
 WndClass.hbrBackground=CreateSolidBrush(RGB(255,255,255));
 //(HBRUSH)GetStockObject(BLUE_BRUSH);//배경색상 설정
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);  //커서지정
 WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION); //마우스지정
 WndClass.hInstance=hInstance; //클래스를 등록하는 프로그램 번호
 WndClass.lpfnWndProc=WndProc; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
 WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
 WndClass.lpszMenuName=NULL;//메뉴지정, NULL이므로 생략
 WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
 
 RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
 //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
 
 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
  CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
 //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
 //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
 //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.
 
 ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
 //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

 //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
 while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
 {
  TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
  DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
     //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
 }
 return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
 HDC hdc;
 PAINTSTRUCT ps;


 
 switch (iMessage) 
 {
 

  case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
  PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
  return 0;
  

  
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  SetPixel(hdc,10,10,RGB(255,0,0));
  Line(hdc,125,100,200,25);
  Line(hdc,200,25,275,100);
  Rectangle(hdc,125,100,275,250);
  Rectangle(hdc,150,130,180,160);
  Rectangle(hdc,350,35,420,115);
  Ellipse(hdc,350,35,420,115);
  EndPaint(hWnd,&ps);
  return 0;
  

 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
   //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}

=================================================================================
================================================================================
메시지 박스
#include<windows.h>
int
 Score=0;
TCHAR str[128];

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
HINSTANCE g_hlnst;    //전역변수
LPCTSTR lpszClass=TEXT("메시지박스 실험");//전역변수, 윈도우클래스를 정의하는데 사용, 타이틀바에 표시됨.
void Line(HDC hdc, int x1, int y1,int x2, int y2)
{
  MoveToEx(hdc,x1,y1,NULL);
  LineTo(hdc,x2,y2);
}
void MyTextOut(HDC hdc,int x,int y,LPCTSTR Text) //TextOut함수같은경우는 문자열의길이를 넘겨야한다 하지만
                        //그수고를 덜기위해서 만든 함수
{
  TextOut(hdc,x,y,Text,lstrlen(Text));
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevlnstance,LPSTR lpszCmdParam, int nCmdShow)
//엔트리포인트는 main()이 아니라 WinMain(),이다.
//윈도우를 만들고 화면에 표시하기만 할 뿐, 대부분의 일은 아래의 함수에서 이루어진다.
//WinMain에서 하는 가장 중요한 일은 메인 윈도우를 만드는 일이다.
{
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;//만들어질 윈도우의 여러가지 특성을 정의하는 구조체
  g_hlnst=hInstance;//메인함수의 첫번째 인자인 hInstance를 전역변수에 대입

  WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
  WndClass.cbWndExtra=0;//않을 때는 0으로 지정한다.
  WndClass.hbrBackground=CreateSolidBrush(RGB(255,255,255));
  //(HBRUSH)GetStockObject(BLUE_BRUSH);//배경색상 설정
  WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);  //커서지정
  WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION); //마우스지정
  WndClass.hInstance=hInstance; //클래스를 등록하는 프로그램 번호
  WndClass.lpfnWndProc=WndProc; //윈도우의 메시지 처리함수를 지정(여기는 WndProc)
  WndClass.lpszClassName=lpszClass;//이름지정, 전역변수를 대입하므로 "First"가 들어감
  WndClass.lpszMenuName=NULL;//메뉴지정, NULL이므로 생략
  WndClass.style=CS_HREDRAW|CS_VREDRAW;  //윈도우의 스타일 정의
  
  RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
  //윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
  
  hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL|WS_THICKFRAME,CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
  //등록된 클래스를 기본으로 실제 윈도우 생성(메모리에 진입)
  //이 함수의 인자들은 위에서 등록한 내용들이 각각의 인자로 들어온다.
  //이 함수는 윈도우에 관한 모든 정보를 메모리에 만든후 대표 번호인 윈도우 핸들을 반환한다.
  
  ShowWindow(hWnd,nCmdShow); //화면에 출력하는 함수. //첫번째 인자는 출력하고자 하는 윈도
  //우의 핸들이며 CreateWindow함수가 리턴한 값이다. 두번째 인자는 출력하는 방법 지정.

  //아래의 While문은 프로그램 메시지를 처리하는 부분이다.
  while(GetMessage(&Message,NULL,0,0)) //메시지를 읽어들여서 false가 리턴될때 까지 반복
  {
    TranslateMessage(&Message); //키보드에 이벤트가 발생하면 그 것을 나타 내 준다.
    DispatchMessage(&Message);  //받은 메시지를 WndProc함수로 전달한다
          //그러면 그 함수에서 메시지를 점검하여 동작하게 된다.
  }
  return (int)Message.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam, LPARAM lParam)
//사용자와 시스템이 보내오는 메시지를 처리하는 함수. (운영체제에 의해 호출)
{
  HDC hdc;
  PAINTSTRUCT ps;

  wsprintf(str,TEXT("value %d"),Score);
  
  switch (iMessage) 
  {
  

    case WM_DESTROY:   //사용자가 프로그램을 끝내려고 한다면
    PostQuitMessage(0);//이 함수를 호출하여 &message에 FALSE를 리턴한다.
    return 0;
        
  
    case WM_LBUTTONDOWN:
      if(MessageBox(hWnd,TEXT("마우스 왼쪽 버튼을 눌렀습니까?"),str,MB_ICONINFORMATION | MB_OKCANCEL)==IDOK)
      {
        Score++;
    SetWindowText(hWnd,str);
      
      }
    
      
    return 0;
    case WM_RBUTTONDOWN:
      if(MessageBox(hWnd,TEXT("마우스 왼쪽 버튼을 눌렀습니까?"),str,MB_ICONSTOP|MB_YESNO)!=IDYES)
      {  
    Score++;     
    SetWindowText(hWnd,str);
        
      }
    
    
    return 0;
    

  }
  return(DefWindowProc(hWnd,iMessage,wParam,lParam));//실제로 각 이벤트들이
      //수행되는 부분이다. (default이므로 별다른 코드가 필요없다.)
}