20141007 (C++ 정보은닉, 캡슐화, 생성자, 소멸자, 비디오처리)

153일차








-----------

C++

-----------




------- 정보은닉, 캡슐화


--- 정보은닉

정보은닉은 말 그대로 외부에 정보를 숨기는 역할이다.

class 내에 접근 지시자로 private와 const 함수가 이에 해당한다.


예제)


class Rectangle

{

private:

Point upLeft;

Point lowRight;


public:

bool InitMembers(const Point &ul, const Point &lr);

void ShowRectInfo() const;

};


클래스 내에 변수들은 private로 외부에서 접근 가능하지 못하고,
InitMembers라는 함수를 통해서만 수정이 가능하게 만들어 놓았다.

ShowRectInfo() 함수 선언 뒤에 const 가 선언되어 있는데,

이 함수는 내부 데이터를 읽기만 한다는 뜻이다.

만약 이 함수에서 데이터를 쓰는 코드가 들어 있을 시, 컴파일때 에러 처리가 된다.

또 const 함수 내에서 다른 함수를 호출시 그 함수도 const 옵션이 붙어 있어야만

호출이 가능하지, 붙지 않으면 이것 또한 컴파일시 에러 처리가 된다.




--- 캡슐화

예를 들어 함수 1, 2, 3 이 있는데 1 -> 2 -> 3 순으로 실행 되어야만 기능이 제대로 되는 함수라 하자.

그런데 프로그래머가 작성 중 이걸 잊어버리고 잘 못 코딩 할 경우 이것을 방지해 주는 역할이다.


예제)

#include <iostream>


using namespace std;


class SinivelCap

{

public:

void Take() const

{

cout << "콧물이 싹~ 납니다." << endl;

}

};


class SneezeCap

{

public:

void Take() const

{

cout << "재채기가 멎습니다." << endl;

}

};


class SnuffleCap

{

public:

void Take() const

{

cout << "코가 뻥 뚫립침니다." << endl;

}

};


class CONTAC600

{

private:

SinivelCap sin;

SneezeCap sne;

SnuffleCap snu;


public:

void Take() const

{

sin.Take();

sne.Take();

snu.Take();

}

};


class ColdPatient

{

public:

void TakeCONTAC600(const CONTAC600 &cap) const

{

cap.Take();

}

};


int main()

{

CONTAC600 cap;

ColdPatient sufferer;

sufferer.TakeCONTAC600(cap);


return 0;

}



위의 예제를 통해 보았듯이 이 클래스를 실행하면 항상

콧물 -> 재채기 -> 코 뻥.. 순으로 실행이 된다. 이런 것을 캡슐화라한다고 한다.




정보은닉이나 캡슐화나 프로그래머들이 소스 작성 시

에러를 줄여 안전성을 높이기 위한 기능이다.








------- 생성자, 소멸자

생성자는 클래스의 객체 생성시 실행시켜주는 함수?이다.


예제)


class smart

{

public:

int * ip;

};


int main()

{

smart obj1;

smart obj2;

smart obj3;


obj1.ip = 0;

obj2.ip = 0;

obj3.ip = 0;


return 0;

}


위의 예제에서 항상 smart 객체 생성시 ip 값에 0으로 초기화를 해줘야 하는데

매번 해 주기도 개체수가 많아진다면 엄청난 일이 되어 버린다.

그래서 다음과 같이 생성자를 만들어 준다.


class smart

{

public:

int * ip;


public:

smart()

{

ip = 0;

}

};


int main()

{

smart obj1;

smart obj2;

smart obj3;


return 0;

}


이렇게 하고나면 객체가 만들어 지는 즉시 smart()라는 생성자를 실행시켜

초기화를 해준다.

생성자는 클래스 이름과 같게 만들고 함수로 치자면 리턴 타입이 없다.



--- 소멸자

소멸자는 객체가 사라질때 호출되는 함수?이다.


예제)

#include <iostream>


using namespace std;


class smart

{

public:

int * ip;

int iNum;


public:

smart() // default 생성자라 부른다

{

iNum = 0;

cout << iNum << "Default 생성자 호출" << endl;

ip = new int;

}


smart(int iNum) // default 생성자가 아님

{

smart::iNum = iNum;

cout << iNum << "생성자 호출" << endl;

ip = new int;

}


~smart()  // 소멸자

{

cout << iNum << "소멸자 호출" << endl;

delete ip;

}

};


int main()

{

smart obj1(1);

smart obj2(2);

smart obj3(3);

smart obj4;

/*

obj1.ip = 0;

obj2.ip = 0;

obj3.ip = 0;

*/

/* obj1.iNum = 1;

obj2.iNum = 2;

obj3.iNum = 3;

*/

cout << "-----------------------------------------------" << endl;


return 0;

}


결과














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

영상 처리

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


#include <windows.h>

#include "vfw.h"

#pragma comment(lib, "vfw32.lib")


#define BITMAP_MAXSIZE (1024*768*3+10)


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

HINSTANCE g_hInst;

HWND HWndMain;

LPCTSTR lpszClass=TEXT("WiseCat");


int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance

,LPSTR lpszCmdParam,int nCmdShow)

{

HWND hWnd;

MSG Message;

WNDCLASS WndClass;

g_hInst = hInstance;


WndClass.cbClsExtra=0;

WndClass.cbWndExtra=0;

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

WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

WndClass.hInstance=hInstance;

WndClass.lpfnWndProc=WndProc;

WndClass.lpszClassName=lpszClass;

WndClass.lpszMenuName=NULL;

WndClass.style=CS_HREDRAW | CS_VREDRAW;

RegisterClass(&WndClass);


hWnd=CreateWindow(  lpszClass

,lpszClass

,WS_OVERLAPPEDWINDOW

,CW_USEDEFAULT

,CW_USEDEFAULT

,CW_USEDEFAULT,CW_USEDEFAULT

,NULL

,(HMENU)NULL

,hInstance

,NULL);        

ShowWindow(hWnd,nCmdShow);


while(GetMessage(&Message,NULL,0,0))

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}


return (int)Message.wParam;

}


LRESULT CALLBACK FramInfo(HWND, LPVIDEOHDR);


HWND vfw;

BITMAPINFO Bm;

HDC hdc;

BITMAPFILEHEADER * stpBFH;

BITMAPINFOHEADER * stpBIH;

unsigned char * BMbuf;

unsigned int uiPad;


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

{

HANDLE hFile;

PAINTSTRUCT ps;

static unsigned int uiX;

static unsigned int uiY;

DWORD dwRead;


switch(iMessage)

{

case WM_CREATE:

HWndMain = hWnd;


// Bitmap 열고 처리 //시작---------------------------------------------

hFile = CreateFile(TEXT("image.bmp"),

GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(INVALID_HANDLE_VALUE != hFile)

{

BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

CloseHandle(hFile);


stpBFH = (BITMAPFILEHEADER *)BMbuf;

stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


uiX = (unsigned int)(stpBIH->biWidth);

uiPad = uiX%4;

uiY = (unsigned int)(stpBIH->biHeight);

}

// Bitmap 열고 처리 //끝-----------------------------------------------


// 웹캠 설정 // 시작------------------------

vfw = capCreateCaptureWindow(  TEXT("CAM")

,WS_CHILD | WS_VISIBLE

,0

,0

,400

,300

,hWnd

,NULL);


capDriverConnect(vfw,0);

capGetVideoFormat(vfw,&Bm,sizeof(Bm));

Bm.bmiHeader.biWidth  = 320;

Bm.bmiHeader.biHeight = 240;

capSetVideoFormat(vfw,&Bm,sizeof(Bm));

//capDlgVideoFormat(m_capwnd); 

capSetCallbackOnFrame(vfw, FramInfo);

capPreviewRate(vfw, 1);

capPreview(vfw, FALSE);

// 웹캠 설정 // 끝--------------------------

return 0;


case WM_PAINT:

hdc = BeginPaint(hWnd,&ps);

EndPaint(hWnd,&ps);

return 0;


case WM_DESTROY:

free(BMbuf);

PostQuitMessage(0);

return 0;

}

return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}


LRESULT CALLBACK FramInfo(HWND hWnd, LPVIDEOHDR lpData)

{

static int iCntX;

static int iCntY;

static int Jump;

unsigned char * ucpPixel;


// 원본 영상 그리기 // 시작-------------------------------

hdc = GetDC(HWndMain);

StretchDIBits(hdc  , 0

, 0

, Bm.bmiHeader.biWidth

, Bm.bmiHeader.biHeight

, 0

, 0

, Bm.bmiHeader.biWidth

, Bm.bmiHeader.biHeight

, lpData->lpData

, &Bm

, DIB_RGB_COLORS

, SRCCOPY);

// 원본 영상 그리기 // 끝---------------------------------


// 영상 정보 편집 // 시작--------------------------------------------

ucpPixel = BMbuf + stpBFH->bfOffBits - 3;

Jump= 0;

for(iCntY = 0; iCntY < Bm.bmiHeader.biHeight ; ++iCntY)  

{        

for(iCntX = 0; iCntX  < Bm.bmiHeader.biWidth  ; ++iCntX, Jump += 3)

{

ucpPixel = ucpPixel + 3;

if(lpData->lpData[Jump + 2] > 100)

{

continue;

}

else if(lpData->lpData[Jump + 1] > 100)

{

continue;

}

else if(lpData->lpData[Jump + 0] > 50)

{

lpData->lpData[Jump] = *(ucpPixel + 0);  // Blue

lpData->lpData[Jump + 2] = *(ucpPixel + 2);  // Red

lpData->lpData[Jump + 1] = *(ucpPixel + 1);  // Green

}

}

ucpPixel = ucpPixel + uiPad;

}

// 영상 정보 편집 // 끝----------------------------------------------


// 편집된 영상 그리기 // 시작----------------------------

StretchDIBits(hdc  , Bm.bmiHeader.biWidth +20

, 0

, Bm.bmiHeader.biWidth

, Bm.bmiHeader.biHeight

, 0

, 0

, Bm.bmiHeader.biWidth

, Bm.bmiHeader.biHeight

, lpData->lpData

, &Bm

, DIB_RGB_COLORS

, SRCCOPY);

// 편집된 영상 그리기 // 끝------------------------------


ReleaseDC(HWndMain, hdc);


return 0;

}



설정

트랙백

댓글