2016. 9. 19. 23:16

* C++에서 스마트 포인터를 사용하는 공통적인 이유


- 적은 버그

- 스마트 포인터를 사용함으로써 코드의 크기를 줄일 수 있다

- 이보다는 버그를 줄일 수 있는 것이 더 중요한 이유

- 스마트 포인터를 사용할 때는 delete를 명시적으로 호출할 필요가 없으므로 메모리 해제에 대해서는 잊어도 됨


- 자동 초기화

- nullptr로 초기화 하지 않아도 됨

- 디폴트 생성자가 자동으로 생성


- auto_ptr을 사용할 때 auto_ptr이 복사되는 경우 대입되는 객체가 nullptr로 설정됨





- auto_ptr이 아닌 다른 스마트 포인터들은 복사가 될 때 다른 행동을 함

- 예를 들어 다른 스마트 포인터에서는 q = p 문을 실행할 때 q와 p가 동일한 스마트 포인터인 경우 다음과 같은 전략을 취할 수도 있음


- 새로운 복사본 생성 : p가 가리키고 있는 객체에 대한 복사본을 새로 생성한 다음 q가 가리키도록 하는 전략 (copied_ptr.h)

- 소유권 이전 : p와 q가 동일한 객체를 가리키도록 하지만 해제에 관한 소유권을 p에서 q로 이전하는 전략 (owned_ptr.h)

- 참조 카운트 : 동일한 객체를 가리키고 있는 스마트 포인터의 개수를 유지하는 전략, 참조 카운트가 0이 되는 순간 객체를 삭제, q = p 문은 p가 가리키고 있는 객체의 카운트 값을 1 증가 (counted_ptr.h)

- 참조 연결 : 참조 카운트 방식과 비슷, 동일한 객체를 가리키는 모든 스마트 포인터를 circular doubly linked list로 연결 (linked_ptr.h)

- Copy on write : 참조 카운트 혹은 참조 연결 방식은 가리키고 있는 객체가 수정되지 않는 동안 사용, 수정이 필요할 때 새로운 복사본을 생성한 뒤에 복사본에 수정하는 방식 (cow_ptr.h>


- scoped_ptr, shared_array 등


- 매개 변수 목록이 아닌 별도 코드 줄에서 스마트 포인터를 만들어야 특정 매개 변수 목록 할당 규칙으로 인해 아주 작은 리소스 누수도 발생하지 않음



* 단점

- 스마트 포인터가 nullptr인지 체크 불가

- 상속 기반의 변환 제한

- 상수 객체에 대한 포인터 지원 제한

- 구현하기 까다로움

- 이해하기 쉽지 않아 유지 보수도 어려움

- 디버깅이 어려움





2016. 9. 19. 20:54

Visual Studio 에서 


메뉴 - 빌드 - 솔루션 빌드 


아래의 메뉴를 보면 현재의 프로젝트의 빌드가 나온다


그 이름으로 솔루션 탐색기에서 소스를 찾으면 된다

2016. 6. 29. 22:56

The procedure entry point ??4QImage@@AEAAV0@$$QAV0@@Z could not be found in the dynamic link library QtGuid4.dll







여기서 QImage 클래스의 함수가 없다는 뜻인데 두 가지로 판단할 수 있다


1. DLL 이 잘못 만들어져서 함수가 포함되지 않았다

- DLL 다시 만들거나 버전 업그레이드를 한다



2. DLL 이 다른 dll 에 있는 함수를 사용하는데 그 함수가 없다

- 그 함수가 포함된 dll을 추가한다




2016. 6. 17. 16:22

응용 프로그램을 제대로 시작하지 못했습니다(0xc0150002)


이 에러는 Microsoft Visual C++ 2005 (Redistributable) 재배포 가능 패키지 (x86) 가 설치되지 않았을 때 발생하는 에러이다


다음 사이트에 들어가서 다운 받아 설치한다


https://www.microsoft.com/ko-kr/download/details.aspx?id=26347





2016. 5. 18. 01:16

원본 사이트 : http://www.tutok.sk/fastgl/callback.html


* 원 제목 : Callbacks in C++ using template functors


- 도입(Introduction)

객체 지향 프로그래밍의 많은 약속 중에 하나는 재사용 가능한 컴포넌트와 함께 플러그 앤 플레이 소프트웨어 디자인을 허락하는 것이다.

디자이너는 그들의 라이브러리 덩어리로부터 객체를 땡겨올 것이고, 그것들을 가지고 소프트웨어를 함께 만들이 위해 연결할 것이다

C++에서 컴포넌트들과 함께 하는 이 연결은 난감할 수 있고 특히 만약 그것들이 별도로 디자인 되어있으면 더 난감하다

우리는 여전히 상호 작용하는 라이브러리와 응용 프로그램 컴포넌트들로부터 긴 길이 될 것이다

콜백은 독립적으로 개발된 객체들이 함께 연결될 수 있는 메커니즘을 제공한다

그것들은 플러그 앤 플래이 프로그래밍에 필수적인데, 왜냐하면 공장 B의 클래스, 또는 너의 집에서 끓인 클래스의 용어로 그들의 라이브러리를 구현하는 공장 A의 가능성은 0이기 때문이다


콜백은 널리 사용되지만 일반성의 부족으로 최소한이 현재 구현은 다르고 대부분 부족으로부터 고통을 받는다

이 글은 콜백이 무엇이고, 어떻게 그것들이 사용되고, 좋은 콜백 메커니즘에 대한 기준을 설명한다

그것은 현재의 콜백 메서드와 그것들의 약점을 요약한다.

그리고나서 그것은 템플릿 함수자(template functor)- 함수처럼 행동하는 객체-에 기반한 유연한, 파워풀한, 사용하기 쉬운 콜백 기술을 설명한다



* 콜백의 근본(Fundamentals)


- 콜백이란 무엇인가?

응용프로그램 또는 서브 시스템에 특화된 컴포넌트들을 디자인할 때 우리는 종종 어느 컴포넌트끼리 상호작용할지 클래스의 모든 것을 알고 따라서 

명시적으로 이 클래스들로 인터페이스를 코딩한다

그러나 일반적인 목적 또는 라이브러리 컴포넌트를 디자인할 때, 그것은 종종 필수적이거나 모르는 객체를 호출할 때 같이 하기 위해 넣기를 원한다

요구되는 것은 다른 컴포넌트 타임의 용어나 지식으로 쓰여지는 것에 관계 없이 서로를 호출하는 하나의 컴포넌트를 위한 방법이다

그런 '타입 블라인드' 호출 메커니즘을 종종 콜백으로 언급한다


콜백은 아마 간단한 통보, 두가지 의사소통 또는 프로세스에서 일을 분배할 때 사용된다

예를 들어 응용 프로그램 개발자가 클릭할 때 GUI 라이브러리 호출을 응용 프로그램에 특화된 객체로 Button 컴포넌트를 갖기를 원한다

데이터 진입 컴포넌트의 디자이너는 입력 유효성을 위한 응용 프로그램 객체 호출을 위한 능력을 제공하기를 원할 수도 있다

Collection 클래스들은 종종 apply() 함수를 제공하는데, 이것은 그것들이 포함하는 아이템에 대한 응용 프로그램 객체의 멤버 함수를 적용한다


그리고나서 콜백은 응용 프로그램 객체와 함께 상호작용으로 세우기 위해 개발자들이 사용할 수도 있는 일반적인 연결점을 제공하는 컴포넌트 디자이너들을 위한 방법이다

일부 연속적인 점에서 컴포넌트는 응용 프로그램 객체를 콜백한다

의사소통은 함수 호출의 형태를 갖는다 왜냐하면 이것은 C++에서 객체들이 상호작용하는 방법이기 때문이다


콜백은 많은 문맥에서 유용하다

만약 당신이 상용 클래스 라이브러리를 사용한다면 아마도 콜백을 제공하는 최소한 하나의 메커니즘을 봤을 것이다

모든 콜백 구현은 C++ 타입 시스템에 의해 제공된 근본 문제를 다루어야 한다

그러나 당신은 컴포넌트가 디자인 됐을 때 그것의 타입을 모르는 객체들의 멤버 함수들을 호출할 수 있는 컴포넌트들을 빌드할 수 있는가?

C++ 타입 시스템은 우리가 호출하기를 원하는 멤버 함수의 어떤 객체의 타입을 알기를 원하고 종종 진짜 컴포넌트 기반 디자인을 지지하는 것에 매우 유연한 다른 언어들의 팬에 의해 비판 받는다

왜냐하면 모든 컴포넌트들은 서로에 대해 알아야만 하기 때문이다

C++의 강한 타입은 많은 장점들을 금지시키지만 이 유연성의 분명한 부족함을 다루는 것은 강건하고 상호작용하는 클래스 라이브러리들의 확산을 격려할 수도 있다


C++은 사실 매우 유연하고 그 메커니즘은 언어의 확장 없이 이 기능을 제공하는 유연함의 지렛대를 여기에서 나타낸다

특히 템플릿은 이와 같은 문제를 풀기 위한 강력한 도구를 제공한다

만약 당신이 템플릿이 오직 컨테이너 클래스를 위한 것이라고 생각했다면 

이 글을 읽어라~


* 콜백 용어(Callback Terminology)


콜백 메커니즘에서 3가지 요소가 있다 

- 호출자(caller), 콜백 함수(callback function), 피호출자(callee)






2016. 5. 9. 22:48

* 포인터를 사용한 방법의 장점

- 포인터가 인덱스 표기법보다 빠르다

- 이유는 원소의 주소를 계산할 필요가 없다


ex) sum += a[i];

    sum += *a++;


- 디지털 이미지는 배열을 사용하여 저장된다

- 이미지 처리를 할 때 속도를 빠르게 하기 위하여 포인터를 사용한다



void brighten_image(char image[][size])

{


}


* 포인터를 이용하지 않는 버전도 작성

- 배열의 인덱스 표기법으로 위의 프로그램을 변환


- 배열의 이름에 다른 변수의 주소를 대입

- 포인터를 이용하여 배열의 원소들을 참조

- 포인터를 배열의 이름처럼 사용



* 이중 포인터

- 포인터를 가리키는 포인터


int i = 10;

int* p = &i;

int** q = &p;



* 포인터 배열

- 포인터 배열 : 포인터를 모아서 배열로 만든 것


int* ap[10];


1. [] 연산자가 * 연산자보다 우선 순위가 높으므로 ap는 먼저 배열이 된다

2. 어떤 배열이냐 하면 int*(포인터) 들의 배열이 된다



* 2차원 배열에 문자열을 저장


char fruit[4][10]

= { "apple", "blueberry", "orange", "melon"};



* 문자형 포인터 배열

char* fruit[]

= { "apple", "blueberry", "orange", "melon"};



* 배열 포인터

- 배열을 가리키는 포인터


int (*pa)[10];


1. 괄호가 먼저 있으므로 pa는 포인터가 된다

2. 어떤 포인터냐 하면 int [10]을 가리키는 포인터이다.


int a[5] = {1, 2, 3, 4, 5};

int (*pa)[5];;

pa = &a;

std::cout << (*pa)[2] << std::endl;



int arr[10];

int *parr;

int (*parr2)[10];


parr = arr;

parr2 = &arr;


arr[3] = 20;

std::cout << parr[3] << std::endl;

std::cout << (*parr2)[3] << std::endl;














2016. 4. 28. 15:19

Builder 패턴

프로그래밍/C++ 2016. 4. 28. 15:19

* Builder Pattern - 빌더 패턴


- 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 

   서로 다른 표현 결과를 만들수 있게 하는 패턴

- 복잡한 객체 생성을 표현으로부터 분리

- 이렇게 함으로써 같은 생성 과정에서 다른 표현을 만들어냄


- 쉽게 말해서 하나의 객체를 생성할 때 객체를 이루는 구성요소들을 

  분리하여 객체의 세부 구성 요소 클래스들을 별도로 만들고

  그 구성 요소 클래스들을 조합하여 하나의 객체를 만듦

- 자동차를 만든다고 하면 자동차의 부품들을 모아서 하나의 자동차를 만듦


- Builder : 제품(객체)를 생성하는 추상 인터페이스

- Concrete Builder : Builder의 구현 클래스

다른 객체를 생성할 수 있도록 하는 구체적인 클래스

객체를 만들기 위해 부품을 생성하고 조립

- Director : 객체 생성의 정확한 순서를 다루는 부분에 책임

              ConcreteBuilder를 인자로 받아서 필요한 동작을 수행

- Product : Builder를 이용해서 Director가 만들어낸 최종 객체


- 빌더는 복잡한 객체를 한 단계 한 단계씨기 생성하는데에 초점을 맞춘다

- 추상 팩토리는 제품 객체들의 집단을 강조

- 생성되는 객체가 단일 객체이던지, 복잡한 객체던지 상관 없다

- 빌더는 마지막 단계에 반환하지만, 추상 팩토리가 하는 것처럼 

   제품을 바로 얻어냄

- 빌더는 주로 복잡한 객체를 생성(Composite)

- 설계는 팩토리 메서드를 사용해서 시작하지만 설계자가 어느 부분에서

  유연성에 따라 추상 팩토리, 프로토타입 또는 빌더 등으로 발전

- 빌더는 어떤 컴포넌트를 만드는지 정하기 위해 다른 패턴 중 하나 사용 

  추상 팩토리, 빌더, 프로토타입은 싱글톤을 구현에 사용

- 빌더는 Fluent Interface의 좋은 지원자

2016. 2. 26. 14:29

* 스마트 포인터

- C++ 언어에서 사용되는 보통의 포인터처럼 기능을 제공하도록 설계된 C++ 객체


* 스마트 포인터 사용 이유


1. 생성과 소멸 작업을 조절할 수 있음

- 스마트 포인터가 생성되고 소멸되는 시기를 프로그래머가 결정

- 스마트 파인터는 생성될 때 기본 값을 널(nullptr) 포인터를 가지기 때문에, 값을 주지 않으면 초기화되지 않는 멍텅구리 포인터가 일으키는 골치 아픔을 원천적으로 봉쇄

- 객체를 가리키고 있던 최후의 포인터가 소멸될 때, 자동으로 그 객체를 삭제하는 기능도 가지고 있음


2. 복사와 대입 동작을 조절할 수 있음

- 스마트 포인터가 복사되거나 대입될 때 일어나는 일을 프로그래머가 결정

- 어떤 경우에는 포인터가 가리키고 있는 객체를 자동으로 복사(깊은 복사)

- 어떤 경우에는 포인터 자체만 복사 (얕은 복사)

- 이외의 경우에는 어떤 동작도 전혀 하지 않음

- 바라는 바를 그대로 이행하는 포인터가 스마트 포인터


3. 역참조 동작을 조절(dereferencing)

- 사용자가 스마터 포인터가 가리키는 객체를 가져오려고 할 때 결정

- 지연 방식의 데이터/명령어 가져오기를 구현 (fetching)


2016. 2. 26. 13:58

* 참조 카운팅 

- 여러 개의 객체들이 똑같은 값을 가졌으면, 그 객체들로 하여금 그 값을 나타내는 하나의 데이터를 공유하게 해서 데이터의 양을 절약하는 기법

2016. 1. 19. 13:48

// int -> string


// vc++ 11 이전 

#include <sstream>


int num = 5;

std::stringstream stream;

stream << num;

std::string str = stream.str( );


// vc++ 11 이후

int num = 5;

std::string str = std::to_string( num );



// string -> int

// vc++11 이전

std::string str( 5 );

int num = atoi(str.str( ) );


// vc++11 이후

std::string str( 5 );

int num = std::stoi( str );

2015. 12. 30. 18:25

void main()

{

#if defined(WIN32) || defined(WIN64)

#ifdef _DEBUG

#include <crtdbg.h>

 // _CRTDBG_ALLOC_MEM_DF ==> _CLIENT_BLOCK 에 메모리를 할당에 대해서 덤프

 // _CRTDBG_LEAK_CHECK_DF ==> 프로그램이 종료될 때 자동으로 _CrtDumpMemoryLeaks() 를 호출하여 메모리 누수시 덤프

 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

 // 해제 안되는 new 의 파일과 라인수를 파악한다.

 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)


 // 메모리 누수시 블록숫자값(출력창의{1234})을 주면 메모리 공간을 확보하는 시점에 브레이크포인트가 걸린다.

 _CrtSetBreakAlloc(1359);

#endif

#endif

}

2015. 12. 16. 23:25

문서 파일 객체 - 응용 프로그램이 생성


NewDocument() 함수 

-> 운영체제가 어떤 응용 프로그램을 생성하던지 상관없이 똑같이 호출

NewDocument() 함수 구현

-> 응용 프로그램에 따라 고유한 문서 파일 객체를 생성


=> 운영체제가 호출하는 인터페이스는 응용 프로그램에 상관없이 동일하게 유지되면서, 응용 프로그램마다 생성되는 객체는 각 응용 프로그램마다 고유하게 만들어지도록 하는가?


=> 운영체제가 호출하는 NewDocument() 인터페이스를 어떻게 배치, 

    어떻게 구현

* HwpApplication 클래스 -> HwpDocument 객체 생성

* MsWordApplication 클래스 -> MsWordDocument 객체 생성


1. 응용 프로그램마다 NewDocument() 멤버 함수 구현

2015. 11. 16. 14:56

Command Pattern

프로그래밍/C++ 2015. 11. 16. 14:56

* 문제 사례 설명

- 예제

- 웹으로 게시판 서비스를 제공하는 프로그램을 작성한다고 가정

- 이 때 게시판 프로그램은 CGI(Common Gateway Interface) 형태로 작성

- 웹 브라우저로부터 전달된 요청이 웹 서버를 거쳐 표준 입력 형태로 게시판 프로그램에 전달

- 게시판 프로그램에서 표준 출력 형태로 전송한 결과가 웹 서버를 거쳐 이용자가 보는 웹 브라우저의 화면으로 전달되는 형태

- 이 때 웹 브라우저로부터 전달되는 요청의 종류는 "cmd=login"과 같이 cmd라는 이름의 값으로 지정되는 문자열에 의하여 


- 여기서 문제는 게시판에서 제공하는 서비스 항목이 처음부터 명확해지지 않고 개발도중에 점차 추가될 가능성이 많음

- 예를 들어 처음에는 이용자 로그인과 게시물 목록 보여주기, 게시문 본문 읽기 서비스 항목만 있다가 

- 점차 게시물 쓰기, 게시물 추천하기 등의 서비스 항목이 추가

- 이럴 경우 어떻게 하면 기존에 개발해 두었던 부분들을 수정하지 않고 쉽게 새로운 서비스 항목을 추가할 수 있는가?


* 다양한 접근 방법 및 Command 패턴

- CGI 형태로 게시판 프로그램을 작성할 때 게시판에서 제공하는 서비스 항목을 쉽게 추가할 수 있도록 설계

- 여기서 서비스 항목이 추가된다는 것은 뒤집어 생각하면 게시판 프로그램으로 전달되는 요청의 종류가 추가

- 이는 곧 요청에 따라 처리해야 할 작업이 추가

- 주어진 문제는 게시판 프로그램에 새로운 요청 처리를 수행하는 작업을 수시로 쉽게 추가하려면 어떤 구조의 설계를 하는 것이 좋은가?




Command Pattern 구현 관련 사항

- Execute() 멤버 함수의 구현에 대해 생각해보면

  단순히 요청을 처리할 객체의 멤버 함수를 호출하는 형태부터

  요청 자체를 직접 처리하는 형태까지 다양할 수 있다

- 이 때 후자 방식은 Command 클래스가 다른 클래스에 의존하지 않게 구현   하고 싶을 때나 요청 처리를 수행할 적당한 객체가 없을 때 또는

  작업 수행과 관련된 객체를 묵시적으로 알고 있을 때 유용


* 직접 처리하는 경우의 문제점

- 클라이언트 프로그램이 요청을 처리할 객체를 일일이 알고 있어야 함

- 새로운 종류의 요청 처리가 필요할 때마다 Client 프로그램을 수정


1. 클라이언트 프로그램이 요청을 처리할 객체를 일일이 알 필요가 없는 방법

- 요청을 처리하는 객체들의 클래스를 모두 동일한 상속 구조에 포함

- 여기서 클래스들을 동일한 상속 구조에 포함시켜 정의하는 것인 각 클래스들이 동일한 인터페이스를 가지도록 만드는 것

- 이렇게 되면 클라이언트는 처리해야 할 요청의 종류에 상관 없이 동일한 형태로 프로그램 작성이 가능

- 그러나 이 방법은 요청을 처리하는 객체들의 클래스가 별다른 관련도 없는데 같은 상속 구조 하에서 동일한 자료형으로 다루어지게 만드는 것


- 또 다른 방법

- 클라이언트가 하던 역할을 대신하는 객체를 두는 것

- 요청의 종류에 따라 처리 객체를 지정하는 일을 대신 수행하는 객체를 정의하고 클라이언트가 하던 역할을 모두 이 객체에게 위임

- 이 방법을 적용할 경우 클라이언트는 당연히 요청을 처리할 객체에 대해 일일이 몰라도 됨

- 왜냐하면 그 일을 위임받은 객체가 따로 존재하기 때문

- 그렇다면 이 때 클라이언트의 역할을 위임받은 객체의 클래스는 실제 어떻게 설계되는 것이 좋은가?

- 문제의 핵심은 요청의 종류에 따라 그것을 처리할 객체에 대한 정보를 저장, 관리하도록 만드는 것

- 이보다 좋은 방법은 요청의 종류 별로 별도의 클래스를 정의해서 그것을 처리할 객체에 대한 정보를 저장, 관리

- 단, 이때 클라이언트 프로그램에서 이들 클래스 객체들을 동일한 방식을 다룰 수 있게 만들어 주기 위해서는 이들 클래스의 상위에 Command 클래스와 같은 추상 클래스를 정의해주는 것이 필요


- 새로운 요청이 추가되더라도 클라이언트가 수정되지 않게 하는 방법

- 클라이언트가 수정되지 않게 만들려면 존재하는 조건 비교 문장이 사라짐

- 주어질 수 있는 값들과 그에 따라 실행해야 할 모듈들을 미리 등록해두었다가 요청이 들어오면 일치하는 모듈을 찾아서 곧바로 찾아서 실행

- 이 방법을 적용하려면 실행해야 할 모듈들을 일반화시켜 저장, 관리할 수 있는 자료형

- 한 가지 방법은 동일한 상속 구조 하에 정의, 각 인터페이스 명을 통일

- 불려질 모듈 별로 각각 별도의 클래스를 정의하고 이들이 동일한 상속 구조에 놓임


- 결국 별도의 클래스 상속 구조를 정의해서 활용





* Execute( ) 멤버 함수로 전달되어야 할 인자가 클래스마다 다를 경우

1. 각 클래스의 생성자의 인자로 

   Execute( ) 멤버 함수에서 사용할 인자를 미리 전달

   요청을 처리할 객체가 각 클래스마다 다르므로,

   생성자를 통해 미리 요청을 처리할 객체를 전달

2. Execute( ) 멤버 함수의 인자로 주어질 것들을 각각 클래스로 정의하고, 

   이들의 상위에 추상클래스를 정의함으로써 

   Execute( ) 멤버 함수가 동일한 자료형의 인자를 가지도록 만드는 방식

   Execute( ) 멤버 함수로 전달되는 인자를 Request 클래스로 정의한 것

   void Execute(Request& request);


* 여러 작업을 한꺼번에 처리할 수 있는 방법

- 삭제 후 삭제된 게시물의 목록 보여주기

  DeleteCommand( )

  ListCommand( )

- MacroCommand 패턴을 이용



* 새로운 요청이 추가될 때마다 

  Command의 하위 클래스를 매번 새로 생성하지 않고 실행할 수 있는 방법

- C++의 template 기법

template <typename Type>

class Command{

public:

    void Execute(Request& request){

        m_object->DoAction(request);

    }


private:

    Type* m_object;

};


다만 이 경우, 요청을 처리하는 객체의 인터페이스가 DoAction( ) 형태 통일


* Template Functor 방식

- 각 요청에 대한 처리 모듈을 미리 등록해두되, Command 패턴에서처럼

  작업을 처리할 객체와 작업 처리 모듈을 감싸주기 위한 클래스를 

  요청의 종류마다 각각 정의하지 말고, Functor라는 클래스를 이용

- 여기서 Functor 클래스는 실제 작업 처리 모듈에 대한 함수 포인터를 내부   적으로 가지고 있는 것

- 작업 처리 모듈이 객체의 멤버 함수일 경우에는 객체에 대한 참조 값과

  멤버 함수에 대한 포인터를 같이 저장, 관리할 수 있게 설계된 것

- 이 때 멤버 함수가 요청에 대한 처리 모듈일 경우 

  객체에 대한 참조 값이 함께 필요한 이유는 멤버 함수는 반드시 객체가 있   어야 실행 가능하기 때문

- Functor 클래스를 정의하는 데 template 기법을 사용하는 이유는

Functor 클래스 내부의 함수 또는 멤버 함수 포인터가 가리키는 실제 함수가

인자를 가진다든지 되돌리는 자료가 있을 경우 이들에 대한 자료형을 표현하기 위해서임

- 아무리 template 기법을 적용하더라도 형식 인자의 개수는 구체적으로 지정되어야 하기 때문에

  Functor 클래스는 내부의 함수 포인터가 가리키는 실제 함수가 몇 개의 인자를 가지는지,

또 되돌리는 자료형이 존재하는지에 따라 각각 다른 클래스로 정의



* Command 패턴 정리


- Command 패턴은 요청을 처리할 작업을 일반화시켜 요청의 종류와는 무관하게 프로그램 작성이 가능하게 만들어 주는 것

- Invoker는 실제 Command 클래스의 Execute() 멤버 함수를 호출해주는 것으로 별도의 클래스로 정의될 수도 있고 클라이언트도 될 수 있음


* 유용한 경우

- 그래픽 사용자 인터페이스(GUI) 등을 구현 시 메뉴나 버튼에 수행할 작업을 일반화 시켜 설정하고자 할 때 유용

- 경우에 따라서는 동일한 메뉴에 대해서 동적으로 다른 Command 클래스 객체를 설정함으로써 동일한 메뉴나 버튼이 선택되더라도 상황에 따라 다른 작업을 수행

- 작업 수행을 요청한 시점과 실제 작업을 수행하는 시점을 달리 하고 싶을 때에도 유용





* 결론

- Command 패턴은 외부로부터 요청이 전달될 때 

  이를 받아주는 프로그램 모듈은 미리 작성해 두고,

  각각의 요청에 대해 요청 처리를 수행하는 모듈은 개별 응용 프로그램마다

  플러그인 시키는 콜백(Callback) 형태의 프로그램 작성에 매우 유용

- 따라서 여러분이 충분한 이해와 함께 많이 활용할 수 있기를 기대






2015. 11. 12. 16:46

솔루션 탐색기에서 .cpp 파일을 지웠지만

실제 vcxproj 파일에서는 삭제되지 않은 경우이다


이 경우에는 vcxproj 파일을 메모장을 읽어들여서 열어서

해당 .cpp 파일이 들어있는 xml 부분을 삭제해주면 된다

2015. 9. 21. 23:31

원   형   char *fgets(char *s, int n, FILE *fp);

기   능   파일에서 n-1문자를 읽어들여 포인터 s가 가리키는 위치에 수록한다.  문자를 읽어들이는 도중 행의 끝에 도달하면 읽기가 중단된다.



원   형   int fscanf(FILE *fp, char *format, ... );

함수값   파일에서 읽혀진 자료의 갯수, 에러 발생시에는 ~1(EOF)



원   형   unsigned fwrite(void *buffer, unsigned size, unsigned n, FILE *fp);

기   능   fp가 가리키는 파일의 현재의 입출력 위치에서 size 바이트의 블록 n개를 읽어(size × n 바이트를 읽어) buffer에 수록

함수값   실제로 입력된 블록의 갯수



출력은 fputs( ), fprintf( ), fwrite( )