2010년/5월
5월24일 C++(SmartPointer,namespace,연산자오버로딩 API(대화상자 후반부)
뽀얀햄스터
2010. 5. 24. 08:46
그리고 옆에 그림에서 기본적인 throw후에 바로 catch로 이동한다.
이경우 동적할당을 받은후 메모리를 반환을 해야하는데...
반환하지 못하고 catch를해서 바로 리턴으로 종료한다.
이럴경우 메모리가 쌓이면 과부화가 걸려서 안좋다. 예외처리시에 이런경우를 잘봐야한다.
그에 대한 내용이다.
이에 대한 해결로 클래스를 사용해보았다.
일단 기본적으로 함수안에 객체를 만들고 그 객체 대한 클래스가 소멸할시에 메모리 반환이다 하지만 중요한점은 얼마만큼 크기가 동적할당되어있는지를 받아와야한다. 동적할당 크기 만큼 받아오기 힘들다그래서
char * const ptr을 사용해서
ptr의 크기를 고정시켜두고
:ptr(p)를 통해서 생성자로 크기를 넘긴다 100이기에 ptr은 100의 크기가 된다. 그리고 소멸자로 함수가 종료할때 delete[]ptr로 반환한다.
다음 C++에서 제공하는 클래스에 대한내용이다 라이버리에서 방금 함수를 자동으로 제공해준다.
C++에서 클래스 안에서 예외가 생성될시에..객체는 생성 되지 않는다.
namespace
일반적으로 이것은 중복선언과 공간에 대한이야기이다.
기본적으로 C코드인경우
#include<stdio.h>
int val=100;
int main()
{
int val=100;
::val+=1;
::val+=1;
}
전역변수의 있는 val의값을 증가시키위해서 :: 스코프연산자를 통해서 전역을 가르킬수 있다.
하지만 C++에서는 이경우 namespace라는 이름공간키워드를 한것이다.
using namespace std; 같은경우는 using std사용하고 그것을 namespace로 std라는 이름공간으로 함수를 사용하겠다는 뜻이다. c++에서 전역에 시작하기전에 using namespace std;로 전체에 사용할수 있게 한다는것이다 그래서
::cout<<"cout..test"<endl;같은경우 std를 가져오기위해서 std::cout을 해야한다.
==연산자 오버로딩=
#include<iostream> //복소수 클래스 생성
using namespace std;
class Comp
{
private:
int Real; //실수부
int Img; //Image,허수부
public:
Comp(int Real,int Img)
{
this->Real=Real;
this->Img=Img;
}
friend Comp operator + (const Comp & Left,const Comp & Right);
friend ostream & operator <<(ostream & Left,const Comp & Right);
friend Comp operator - (const Comp & Left,const Comp & Right);
};
Comp operator + (const Comp & Left,const Comp & Right) //함수 이름은 + 클래스에 +만들기 위한 함수
{ //오버로딩 인터페이스만 변경.. (연산자오버로딩)
int Real = Left.Real+Right.Real;
int Img = Left.Img+Right.Img;
return Comp(Real,Img); //임시객체
}
Comp operator - (const Comp & Left,const Comp & Right) //함수 이름은 + 클래스에 +만들기 위한 함수
{
int Real = Left.Real-Right.Real; //오버로딩 인터페이스만 변경.. (연산자오버로딩)
int Img = Left.Img-Right.Img;
return Comp(Real,Img); //임시객체
}
ostream & operator <<(ostream & Left,const Comp & Right)
{
if(0>Right.Img)
{
Left<<Right.Real<<Right.Img<<'i'<<endl;
return Left;
}
Left<<Right.Real<<'+'<<Right.Img<<'i'<<endl;
return Left;
}
/*
일반적인 사칙연산
int operator +(const int& Left,const int & Right)
{
return Left+Right;
}
*/
int main()
{
Comp Num1(100,22);
Comp Num2(150,42);
Comp Num3(0,0);
Num3=Num2+Num1;
// cout<<Num3.Real<<'+'<<Num3.Img<<'i'<<endl;
cout<<Num3;
Num3=Num1-Num2;
cout<<Num3;
Num3=Num2-Num1;
cout<<Num3;
return 0;
}
API전역변수의 있는 val의값을 증가시키위해서 :: 스코프연산자를 통해서 전역을 가르킬수 있다.
하지만 C++에서는 이경우 namespace라는 이름공간키워드를 한것이다.
using namespace std; 같은경우는 using std사용하고 그것을 namespace로 std라는 이름공간으로 함수를 사용하겠다는 뜻이다. c++에서 전역에 시작하기전에 using namespace std;로 전체에 사용할수 있게 한다는것이다 그래서
::cout<<"cout..test"<endl;같은경우 std를 가져오기위해서 std::cout을 해야한다.
==연산자 오버로딩=
#include<iostream> //복소수 클래스 생성
using namespace std;
class Comp
{
private:
int Real; //실수부
int Img; //Image,허수부
public:
Comp(int Real,int Img)
{
this->Real=Real;
this->Img=Img;
}
friend Comp operator + (const Comp & Left,const Comp & Right);
friend ostream & operator <<(ostream & Left,const Comp & Right);
friend Comp operator - (const Comp & Left,const Comp & Right);
};
Comp operator + (const Comp & Left,const Comp & Right) //함수 이름은 + 클래스에 +만들기 위한 함수
{ //오버로딩 인터페이스만 변경.. (연산자오버로딩)
int Real = Left.Real+Right.Real;
int Img = Left.Img+Right.Img;
return Comp(Real,Img); //임시객체
}
Comp operator - (const Comp & Left,const Comp & Right) //함수 이름은 + 클래스에 +만들기 위한 함수
{
int Real = Left.Real-Right.Real; //오버로딩 인터페이스만 변경.. (연산자오버로딩)
int Img = Left.Img-Right.Img;
return Comp(Real,Img); //임시객체
}
ostream & operator <<(ostream & Left,const Comp & Right)
{
if(0>Right.Img)
{
Left<<Right.Real<<Right.Img<<'i'<<endl;
return Left;
}
Left<<Right.Real<<'+'<<Right.Img<<'i'<<endl;
return Left;
}
/*
일반적인 사칙연산
int operator +(const int& Left,const int & Right)
{
return Left+Right;
}
*/
int main()
{
Comp Num1(100,22);
Comp Num2(150,42);
Comp Num3(0,0);
Num3=Num2+Num1;
// cout<<Num3.Real<<'+'<<Num3.Img<<'i'<<endl;
cout<<Num3;
Num3=Num1-Num2;
cout<<Num3;
Num3=Num2-Num1;
cout<<Num3;
return 0;
}
대화상자 컨트롤과의통신
=main.cpp=
#include <windows.h>//API함수들의 원형과 사용하는 상수들이 정의 되어 있다.
#include "MsgProc.h"
//전역변수 선언
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LPCTSTR lpszClass = TEXT("First"); //const char * //lpszClass : 윈도우 클래스를 정의하는데 사용
//
typedef struct MESSAGEMAP
{
UINT iMessage;
LRESULT (*lpfnMsgProc)(HWND,WPARAM,LPARAM);
}MESSAGEMAP;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lPSZCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass; //구도체 선언
WndClass.cbClsExtra=0;//특수한 목적에 사용되는 여분의 공간, 사용하지
WndClass.cbWndExtra=0;//않을 때는 0으로 지정한다.
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_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 | CS_DBLCLKS; //윈도우의 스타일 정의
RegisterClass(&WndClass);//이런 이런 특성을 가진 윈도우를 앞으로 사용하겠다고 등록함.
//윈도우를 만들려면 윈도우 클래스를 등록한 후 CreateWindow함수를 호출한다.
//CreateWindow : 메모리에 윈도우 생성
//윈도우 클래스 지정하는 문자열,
hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,NULL, (HMENU)NULL, hInstance, NULL);
// 4.화면에 윈도우 표시
ShowWindow(hWnd,nCmdShow);
// 5.사용자로부터의 메시지 처리 루프
while(GetMessage(&Message, NULL, 0, 0)) //메시지 큐에서 메시지 읽어옴
{
TranslateMessage(&Message); //키보드 입력 처리
DispatchMessage(&Message); // 큐에서 꺼낸 메시지를 WndProc함수의 iMessage
}
return (int)Message.wParam; //메시지 루프 종료후 이프로그램을
DialogBox(hInstance,MAKEINTRESOURCE(107),HWND_DESKTOP,AboutDlgProc);
}
//WndProc : 사용자와 시스템이 보내오는 메시지를 처리
//WinMain 은 초기화 하고 시작시키기만 하므로 모양이 일정
//WndProc은 프로그램의 실질적이고도 고유한 처리를 하는 곳이므로
//CALLBACK : APIENTRY와 마찬가지로 _stdcall로 정의되어 있다
//운영제제가 호출하는 함수는 CALLBACK, LRESULT = 4바이트 long
typedef struct DMESSAGEMAP
{
UINT iMessage;
BOOL (*lpfnMsgProc)(HWND,WPARAM,LPARAM);
}DMESSAGEMAP;
BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT iMessage, WPARAM wParam,LPARAM lParam)
{
int i;
static DMESSAGEMAP dMessageMaps[]=
{
{WM_INITDIALOG,OnInitDialog},
{WM_COMMAND,OnDlgCommand}
};
for(i=0;i<sizeof(dMessageMaps)/sizeof(dMessageMaps[0]);++i)
{
if(dMessageMaps[i].iMessage==iMessage)
return (*dMessageMaps[i].lpfnMsgProc)(hDlg,wParam,lParam);
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM IParam)
{
int i;
static MESSAGEMAP MessageMaps[] =
{
{WM_CREATE,OnCreate},
{WM_COMMAND,OnCommand},
{WM_LBUTTONDOWN,OnLButtonDown},
{WM_PAINT,OnPaint},
{WM_DESTROY,OnDestroy}
};
for(i=0;i<sizeof(MessageMaps)/sizeof(MessageMaps[0]);i++)
{
if(MessageMaps[i].iMessage == iMessage)
{
return (*MessageMaps[i].lpfnMsgProc )(hWnd,wParam, IParam);
}
}
return(DefWindowProc(hWnd, iMessage, wParam, IParam));
}
#include "MsgProc.h"
#include "resource.h"
int Age;
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM IParam)
{
return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM IParam)
{
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM IParam)
{
DialogBox(g_hInst,MAKEINTRESOURCE(107),hWnd,AboutDlgProc);
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM IParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM IParam)
{
PostQuitMessage(0);
return 0;
}
BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
SetDlgItemInt(hDlg,1002,Age,FALSE);
CheckRadioButton(hDlg,1003,1004,1003);
return TRUE;
}
BOOL OnDlgCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hDlg,IDOK);
Age=GetDlgItemInt(hDlg,1002,NULL,FALSE);
return TRUE;
case IDCANCEL:
EndDialog(hDlg,IDCANCEL);
return TRUE;
}
return FALSE;
}
resource.h
#ifndef __MSGPROC_H_
#define __MSGPROC_H_
#include <windows.h>
#include "resource.h"
BOOL CALLBACK AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
BOOL OnInitDialog(HWND, WPARAM, LPARAM);
BOOL OnDlgCommand(HWND, WPARAM, LPARAM);
void DrawBitmap(HDC hdc,int x, int y,BITMAP hBit);
LRESULT OnCreate(HWND, WPARAM, LPARAM);
LRESULT OnCommand(HWND, WPARAM, LPARAM);
LRESULT OnLButtonDown(HWND, WPARAM, LPARAM);
LRESULT OnPaint(HWND, WPARAM, LPARAM);
LRESULT OnDestroy(HWND, WPARAM, LPARAM);
static HINSTANCE g_hInst;
#endif
=결과값-
InfoDlg와대화상자체크