HTTP Method

Programming/Network 2010. 6. 6. 17:39

1) GET  : URL로 자원 또는 파일을 달라고(get) 요청함

2) POST : Request 에 첨부한 몸체정보를 서버로 보내어, 요청한 URL 로 이 정보를 넘겨주라고 요청함. 용량이 큰 GET, 부가정보를 가진 GET

3) HEAD : GET이 무엇을 리턴하든 간에 헤더 정보만 요청함.
               이는 Response 의 몸체 정보가 없다는 것만 삐면 GET 과 동일함.
               요청한 URL 로부터 요청한 정보는 빼고 헤더 정보만 가져오는 것임.

4) TRACE : 요청한 메시지의 루프백(loopvack) 테스트를 요청함. 
                 서버로부터 받은 내용을 클라이언트 쪽에서 확인하기 위해 사용.
                 테스트 목적 또는 문제 해결을 위해 사용함

5) PUT : 동봉한 몸체 정보를 요청한 URL 로 올리기 위해 사용함.

6) DELETE : 요청한 URL에 있는 자원이나 파일을 삭제하기 위해 사용함.

7) OPTION : 요청한 URL이 응답할 수 있는 HTTP 메소드가 무엇인지 요청함.

8) CONNECT : 터널링의 목적으로 연결을 요청함.

[출처] Http Method|작성자 lbiryu

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

HTTP and WWW  (0) 2010.08.21
프록시 서버( proxy server )  (0) 2010.08.21
Post/Redirect/Get  (1) 2010.05.31
트랜잭션 [ transaction ] 이란?  (0) 2010.05.27
세션 [ session ] 이란?  (0) 2010.05.27

설정

트랙백

댓글

세마포어( Semaphore )

Programming 2010. 5. 31. 17:28
세마포어는 병렬 프로그래밍 환경에서 공동 리소스에 여러 프로세스들에 의한 엑세스를 제어하는 전통적인 방법이다. 세마포어는 바이너리와 카운팅의 두가지 형태를 일반적으로 취한다. 바이너리 세마포어는 간단히 "true/false"(locked/unlocked) 플래그이며, 하나의 리소스를 접근하는 것을 제어한다. 카운팅 세마포어는 여러 리소스를 위한 카운터이다. 각 세마포어 타입은 race condition 을 방지하기 위해 사용된다. ( race condition : 프로세스의 결과가 여러 이벤트의 타이밍이나 순서에 예상치 못하게 그리고 심각하게 의존하고 있을 때, 프로세스의 결점이나 문제를 말한다. 멀티 쓰레드 환경에서나 분산 프로그램에서 발생할 수 있다. 출처 : http://en.wikipedia.org/wiki/Race_conditions )
반면에, 세마포어는 리소스 데드락을 방지하는데는 아무런 의미가 없다. ( 예 : 식사하는 철학자 문제 )

Binary semaphore vs. Mutex vs. Event
: 뮤텍스 는 바이너리 세마포어로, 보통 소유권, 우선순위 역전( prioirty inversion ) 방지나 반복과 같은 추가의 특징을 포함한다. 뮤텍스가 특별하고, 더 빠른 루틴에 의해 실행되더라도, 뮤텍스와 세마포어의 차이점은 운영체제 의존도 이다. 뮤텍스는 상호배제에 사용되고, 바이너리 세마포어는 이벤트 알림에 사용되도록 의도된다.
정리하자면, 뮤텍스란, 상호배제로 크리티컬 섹션에 여러 Thread 가 동시에 접근하지 못하고 순차적으로 접근을 할 수 있도록 보장해주는 것을 뜻한다.( 공유 불가능한 자원의 동시 사용을 피함 ) 한 Thread 에서 크리티컬 섹션에서 진행 중일 때 다른 Thread 는 이를 기다렸다가, 크리티컬 섹션에서 작업 중인 Thread 가 크리티컬 섹션에서 벗어나면 기다리던 Thread가 순차적으로 진입을 하게 된다.
세마포어는, 데드락을 피하기 위한 기술로, 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법으로 사용된다.

어떻게 보면 두개는 비슷한 것 같다. 명확히 차이를 말 못하겠다.. -_-; 어쿠.. 다음 기회에..ㅎ

출처 : http://en.wikipedia.org/wiki/Semaphore_(programming)

'Programming' 카테고리의 다른 글

ARM C Compiler  (0) 2010.09.18
[makefile]commands commence before first target 에러  (0) 2010.07.07
Event-driven programming  (0) 2010.05.31
undefined reference  (0) 2010.03.26
XML 이란?  (0) 2010.03.26

설정

트랙백

댓글

Event-driven programming

Programming 2010. 5. 31. 16:42
Event-driven programming 또는 event-based programming은 프로그래밍 방법론 중에 하나로써, 프로그램의 흐름이 이벤트에 의해 결정이 된다. 다른 프로그램이나 쓰레드의 메시지나 사용자 행동이나 센서의 출력과 같은 이벤트가 있다.
어플리케이션이 이벤트를 선택 또는 이벤트를 감지하고, 이벤트를 처리하는 분명한 두 섹션을 가지는 어플리케이션 아키텍쳐 기술로 정의가 될 수도 있다.

Contrast with batch programming
: 배치 프로그램에서, 프로그램의 흐름은 프로그래머의 의해 결정이 된다. 배치 프로그래밍이 초보 프로그래밍 수업에서 가르치는 스타일 이라고 하더라도, 더 복잡한 event-driven programming 은 현대 대화형 프로그램의 표준 아키텍쳐이다.

출처 : http://en.wikipedia.org/wiki/Event-driven_programming

event-driven 방식은 윈도우에서 뿐만 아니라 네트워크 통신 등 다양한 분야에서 많이 사용하고 있으며, 이 방식을 사용하게 되면 framework 에 좀 더 빨리 return 을 해줄 수 있게 되어, framework 에서 더 많은 처리를 할 수 있도록 어플리케이션에서 대응을 해줄 수 있다.

'Programming' 카테고리의 다른 글

[makefile]commands commence before first target 에러  (0) 2010.07.07
세마포어( Semaphore )  (1) 2010.05.31
undefined reference  (0) 2010.03.26
XML 이란?  (0) 2010.03.26
serialize ( 직렬화 )  (0) 2010.03.22

설정

트랙백

댓글

Post/Redirect/Get

Programming/Network 2010. 5. 31. 15:51

Post/Redirect/Get( PRG ) 는 웹 개발자들이 특정 중복되는 폼을 요청하는 것을 피하도록 돕고, user agent 가 bookmarks, refresh 버튼을 좀더 더 직관적으로 사용할 수 있도록 해주는 흔한 디자인 패턴이다.
( user agent : 분산 컴퓨팅 시스템의 통신에서 사용되는 네트워크 프로토콜을 사용하는 클라이언트 프로그램을 말하고, 이 용어는 주로 World Wide Web 을 엑세스 하는 어플리케이션을 말한다. SIP( Session Initiation Protocol )와 같은 다른 시스템에서는 user agent 라는 용어를 통신 세션의 양 끝을 의미할 때 사용한다.
 출처 : http://en.wikipedia.org/wiki/User_agent )
HTTP POST 요청을 통해 서버에 웹 폼이 전달될 때, 특정 user agents에서 서버 응답을 재요청하려고 하는 웹 사용자는 original HTTP POST 요청 내용을 재요청할 수있고, 중복 웹 구매와 같은 원하지 않았던 결과를 야기할 수 있다. 이 문제를 피하기 위해 많은 웹 개발자 들이 웹페이지를 직접적으로 보내주는 대신에, POST operation이 redirection 명령어를 return 하는, PRG 패턴을 사용하고 있다.( redirection command : HTTP "Location" response header 를 함께 사용하여 HTTP 303 응답 코드 ( 가끔씩 HTTP 302 ) 를 사용하며, 브라우저에게 GTTP GET 요청을 사용하여 다른 페이지를 로드 하라는 명령을 한다 ) 그래서, 웹 사용자는 초기 HTTP POST 요청을 재전송하지않고, 서버 응답을 안전하게 재요청한다.
쉽게 설명을 하자면, 아래 두 그림을 보면 명확하게 알 수 있다.

<그림1>

<그림1>은 Double Submit Problem 으로, 사용자가 구매를 하기위해 "SUBMIT"버튼을 누르면, POST 가 발생하여 DB에 전달이 되고, Confirmation 페이지를 다시 user agent 에게 전달을 해주고 user agent 는 주문이 성공적으로 된 것을 확인 할 수 있는데, 만약 user agent가 refresh page를 하게 되면, 다시 POST 를 발생시키게 되면, 이를 받는 DB 쪽에서는 이 POST 가 refresh 를 위한 것인지, 초기 구매를 위한 것인지 알 수가 없으므로 중복 구매가 발생하게 된다.

<그림2>
<그림2>는 PRG 패턴으로 이를 해결한 것인데, user agent 가 물품 구매시, DB 에 POST 를 전달하고, DB는 user agent에 rediret 를 하고, user agent 는 get을 db 에 요청을 하면, confirmation page를 요청을 하면 그 페이지를 전달해서 볼 수 있고, user agent 가 refresh 를 할 경우, get을 보내어 다시 그 페이지를 볼 수 있게 되어 중복구매를 피할 수 있다.

출처 : http://en.wikipedia.org/wiki/Post/Redirect/Get

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

HTTP and WWW  (0) 2010.08.21
프록시 서버( proxy server )  (0) 2010.08.21
HTTP Method  (0) 2010.06.06
트랜잭션 [ transaction ] 이란?  (0) 2010.05.27
세션 [ session ] 이란?  (0) 2010.05.27

설정

트랙백

댓글

[C++] 복사 생성자

Programming/C++ Language 2010. 5. 31. 11:34

복사 생성자는 지금까지의 평이한 내용에 비해 약간 난이도가 있는 내용이므로 정신을 집중해서 읽을 필요가 있다. 변수를 선언할 때 = 구분자 다음에 상수로 초기값을 지정할 수 있으며 이미 생성되어 있는 같은 타입의 다른 변수로도 초기화할 수 있다. 다음은 가장 간단한 타입인 정수형의 예이다.

int a=3;
int b=a; 

정수형 변수 a는 선언됨과 동시에 3으로 초기화되었다. 그리고 동일한 타입의 정수형 변수 b는 선언과 동시에 a로 초기화되었다. 결국 두 변수는 모두 3의 값을 가지게 될 것이다. 너무 너무 상식적인 코드이며 이런 초기화는 실수형이나 문자형, 구조체 등에 대해서도 똑같이 허용된다. 클래스가 int와 동일한 자격을 가지는 타입이 되기 위해서는 이미 생성되어 있는 같은 타입의 객체로부터 초기화될 수 있어야 한다. 객체에 대해서도 과연 이런 초기화가 성립할 수 있는지 Position 객체로 테스트해 보기 위해 Constructor 예제에 다음 코드를 작성해 보자. 

Position Here(30,10,'A');
Position There=Here;
There.OutPosition(); 

Here 객체가 먼저 (30,10) 위치의 문자 'A'를 가리키도록 초기화되었으며 이어서 There객체는 선언과 동시에 Here객체로 초기화되었다. 이때 멤버별 복사에 의해 There는 Here의 모든 멤버값을 그대로 복사받으며 두 객체는 완전히 동일한 값을 가지게 된다. Position 객체가 내부에 모든 정보를 포함하고 있기 때문에 이런 초기화는 전혀 문제가 없다. 그렇다면 모든 객체에 대해 이런 초기화가 가능한지 Person 객체로도 테스트해 보자. Person1 예제의 main 함수에 다음 테스트 코드를 작성한다. 

void main()
{
     Person Boy("강감찬",22);
     Person Young=Boy;
     Young.OutPerson();
} 

이 코드는 정상적으로 컴파일되며 실행도 되지만 종료할 때 파괴자에서 실행중 에러가 발생하는데 왜 그런지 보자. Young 객체가 Boy객체로 초기화될 때 멤버별 복사가 발생하며 Young의 Name멤버가 Boy의 Name과 동일한 번지를 가리키고 있다. 정수형인 Age끼리 값이 복사되는 것은 아무 문제가 없지만 포인터끼리의 복사는 문제가 된다. Young이 초기화된 직후의 메모리 상황을 그림으로 그려보면 다음과 같으며 두 객체가 힙에 동적 할당된 메모리를 공유하고 있는 모양이다.

이런 상태에서 Young.OutPerson이나 Boy.OutPerson 함수 호출은 아주 정상적으로 실행된다. 그러나 두 객체가 같은 메모리를 공유하고 있기 때문에 한쪽에서 Name을 변경하면 다른 쪽도 영향을 받게 되어 서로 독립적이지 못하다. 이 객체들이 파괴될 때 문제가 발생하는데 각 객체의 파괴자가 Name 번지를 따로 해제하기 때문이다. new는 Boy의 생성자에서 한 번만 했고 delete는 각 객체의 파괴자에서 두 번 실행하기 때문에 이미 해제된 메모리를 다시 해제하려고 시도하므로 실행중 에러가 된다. 정수형은 어떤지 보자.

int a=3;
int b=a;
b=5; 

b가 생성될 때 a의 값으로 초기화되어 a와 b는 같은 값을 가진다. 그러나 이는 어디까지나 초기화될 때 잠시만 같을 뿐이지 두 변수는 이후 완전히 독립적으로 동작한다. b에 5를 대입한다고 해서 a가 이 대입의 영향을 받지 않으며 a에 무슨 짓을 하더라도 b를 어찌할 수는 없다. 정수형의 복사 생성이 이처럼 독립적이므로 사용자 정의형도 이와 똑같이 복사 생성을 할 수 있어야 한다.

Person Young=Boy; 선언문에 의해 Young은 Boy의 멤버값을 복사받지만 이 때의 복사는 포인터를 그대로 복사하는 얕은 복사이다. 따라서 Young은 일시적으로 Boy와 같은 값을 가지지만 Boy의 Name을 빌려서 정보를 표현하는 불완전한 객체이며 독립적이지 못하다. 이 문제를 해결하려면 초기화할 때 얕은 복사를 해서는 안되며 깊은 복사를 해야 하는데 이때 복사 생성자가 필요하다. 얕은 복사가 문제의 원인이었으므로 깊은 복사를 하는 복사 생성자를 만들어 해결할 수 있다. 다음 예제는 Person1예제를 수정하여 Person 클래스에 복사 생성자를 추가한 것이다.  

: Person2

#include <Turboc.h> 

class Person
{
private:
     char *Name;
     int Age; 

public:
     Person(const char *aName, int aAge) {
         Name=new char[strlen(aName)+1];
         strcpy(Name,aName);
         Age=aAge;
     }

    Person(const Person &Other)   {
        Name=new char[strlen(Other.Name)+1];
        strcpy(Name,Other.Name);
        Age=Other.Age;
    }

     ~Person() {
          delete [] Name;
     }

     void OutPerson() {
          printf("이름 : %s 나이 : %d\n",Name,Age);
     }
};

 

void main()
{
     Person Boy("강감찬",22);
     Person Young=Boy;
     Young.OutPerson();
}

복사 생성자는 자신과 같은 타입의 다른 객체에 대한 레퍼런스를 전달받아 이 레퍼런스로부터 자신을 초기화한다. Person복사 생성자는 동일한 타입의 Other를 인수로 전달받아 자신의 Name에 Other.Name의 길이만큼 버퍼를 새로 할당하여 복사한다. 새로 메모리를 할당해서 내용을 복사했으므로 이 메모리는 완전한 자기 것이며 안전하게 따로 관리할 수 있다. Age는 물론 단순 변수이므로 값만 대입받으면 된다.

컴파일러는 Person Young=Boy; 구문을 Person Young=Person(Boy);로 해석하는데 이 원형에 맞는 생성자인 복사 생성자를 호출한다. 실인수 Boy가 Person 객체이므로 Person을 인수로 받아들이는 생성자 함수를 호출할 것이다. 복사 생성자에 의해 Young은 깊은 복사를 하며 메모리에 다음과 같이 완전한 사본을 작성한다.

이제 Young과 Boy는 타입만 같을 뿐 완전히 다른 객체이고 메모리도 따로 소유하므로 각자의 Name을 마음대로 바꿀 수 있고 파괴자에서 메모리를 해제해도 문제가 없다. 복사 생성자에 의해 두 객체가 완전한 독립성을 얻은 것이다.

복사 생성자의 임무는 새로 생성되는 객체가 원본과 똑같으면서 완전한 독립성을 가지도록 하는 것이다. 만약 객체가 데이터 베이스를 사용한다면 이 클래스의 복사 생성자는 새 객체를 위한 별도의 데이터 베이스 연결을 해야 하며 독점적인 자원을 필요로 한다면 마찬가지로 별도의 자원을 할당해야 한다. 그래야 Class A=B; 선언문에 의해 A가 B에 대해 독립적으로 초기화된다.

객체가 인수로 전달될 때

같은 종류의 다른 객체로 새 객체를 선언하는 경우는 그리 흔하지 않다. 그러나 다음과 같이 함수의 인수로 객체를 넘기는 경우는 아주 흔한데 이때도 복사 생성자가 호출된다. 

 void PrintAbout(Person AnyBody)
{
     AnyBody.OutPerson();
} 

void main()
{
     Person Boy("강감찬",22);
     PrintAbout(Boy);
}

 함수 호출 과정에서 형식 인수가 실인수로 전달되는 것은 일종의 복사생성이다. 함수 내부에서 새로 생성되는 형식인수 AnyBody가 실인수 Boy를 대입받으면서 초기화되는데 이때 복사 생성자가 없다면 AnyBody가 Boy를 얕은 복사하며 두 객체가 동적 버퍼를 공유하는 상황이 된다. AnyBody는 지역변수이므로 PrintAbout 함수가 리턴될 때 AnyBody의 파괴자가 호출되고 이때 동적 할당된 메모리가 해제된다. 이후 Boy가 메모리를 정리할 때는 이미 해제된 메모리를 참조하고 있으므로 에러가 발생할 것이다.

복사 생성자가 정의되어 있으면 AnyBody가 Boy를 깊은 복사하므로 아무런 문제가 없다. 객체가 인수로 전달될 때 뿐만 아니라 리턴값으로 돌려질 때도 복사 생성자가 호출된다. 위 테스트 코드를 Person2 예제에 작성해 놓고 실행하면 정상적으로 실행된다. 그러나 복사 생성자를 주석으로 묶어 버리면 다운된다. 함수의 인수로 사용되거나 리턴값으로 사용되는 객체는 반드시 복사 생성자를 제대로 정의해야 한다.

복사 생성자의 인수

복사 생성자의 인수는 반드시 객체의 레퍼런스여야 하며 객체를 인수로 취할 수는 없다. 만약 다음과 같이 Person형의 객체를 인수로 받아들인다고 해 보자.

 Person(const Person Other)
{
     Name=new char[strlen(Other.Name)+1];
     strcpy(Name,Other.Name);
     Age=Other.Age;
}

 복사 생성자 자신도 함수이므로 실인수를 전달할 때 값의 복사가 발생할 것이다. 객체 자체를 인수로 전달하면 복사 생성자로 인수를 넘기는 과정에서 다시 복사 생성자가 호출될 것이고 이 복사 생성자는 인수를 받기 위해 또 다시 복사 생성자를 호출한다. 결국 자기가 자신을 종료조건없이 호출해대는 무한 재귀 호출이 발생할 것이며 컴파일러는 이런 상황을 방관하지 않고 에러로 처리한다.

이런 이유로 복사 생성자의 인수로 객체를 전달할 수는 없다. 그렇다면 포인터의 경우는 어떨까? 포인터는 어디까지나 객체를 가리키는 번지값이므로 한 번만 복사되며 무한 호출되지 않는다. 또한 객체가 아무리 거대해도 단 4바이트만 전달되므로 속도도 빠르다. 복사 생성자가 객체의 포인터를 전달받도록 다음과 같이 수정해 보자.

 Person(const Person *Other) {
     Name=new char[strlen(Other->Name)+1];
     strcpy(Name,Other->Name);
     Age=Other->Age;
}

 Other의 타입이 Person *로 바뀌었고 본체에서 Other의 멤버를 참조할 때 . 연산자 대신 -> 연산자를 사용하면 된다. 그러나 이렇게 하면 Person Young=Boy; 선언문이 암시적으로 호출하는 생성자인 Person(Boy)와 원형이 맞지 않다. 사실 포인터를 취하는 생성자는 복사 생성자로 인정되지도 않는다. 꼭 포인터로 객체를 복사하려면 main의 객체 선언문이 Person Young=&Boy;가 되어야 하는데 그래야 Person 복사 생성자로 Boy의 번지가 전달된다. main 함수까지 같이 수정하면 정상적으로 잘 동작한다.

그러나 이는 일반적인 변수 선언문과 형식이 일치하지 않는다. 기본 타입의 복사 생성문을 보면 int i=j; 라고 하지 int i=&j;라고 선언하지는 않는다. 즉 포인터를 통한 객체 복사 구문은 C 프로그래머가 알고 있는 상식적인 변수 선언문과는 틀리다. 클래스가 기본형과 완전히 같은 자격의 타입이 되려면 int i=j; 식으로 선언할 수 있어야 한다.

그래서 객체 이름에 대해 자동으로 &를 붙이고 함수 내부에서는 전달받은 포인터에 암시적으로 *연산자를 적용하는 레퍼런스라는 것이 필요해졌다. 복사 생성자가 객체의 레퍼런스를 받으면 Young=Boy라고 써도 실제로는 포인터인 &Boy가 전달되어 속도 저하나 무한 호출없이 기본 타입과 똑같은 형식의 선언이 가능하다. 이후 공부하게 될 연산자 오버로딩에도 똑같은 이유로 레퍼런스가 활용된다. C에서는 꼭 필요치 않았던 레퍼런스라는 개념이 C++에서는 필요해진 이유가 객체의 선언문, 연산문을 기본 타입과 완전히 일치시키기 위해서이다.

복사 생성자로 전달되는 인수는 상수일 수도 있고 아닐 수도 있는데 내부에서 읽기만 하므로 개념적으로 상수 속성을 주는 것이 옳다. int i=j; 연산 후 j의 값이 그대로 유지되어야 한다. 결론만 요약하자면 Class 클래스의 복사 생성자 원형은 Class(const Class &)여야 한다.

디폴트 복사 생성자

클래스가 복사 생성자를 정의하지 않으면 컴파일러가 디폴트 복사 생성자를 만든다. 컴파일러가 만드는 디폴트 복사 생성자는 멤버끼리 1:1로 복사함으로써 원본과 완전히 같은 사본을 만들기만 할 뿐 깊은 복사를 하지는 않는다. 만약 디폴트 복사 생성자만으로 충분하다면(Position 클래스의 경우) 굳이 복사 생성자를 따로 정의할 필요는 없다. 이때 만들어지는 디폴트 복사 생성자는 다음과 같을 것이다.

 Position(const Position &Other) {
     x=Other.x;
     y=Other.y;
     ch=Other.ch;
} 

대응되는 멤버끼리 그대로 대입하는데 전부 단순 타입이라 대입만 하면 잘 복사된다. 이런 디폴트 복사 생성자가 있기 때문에 별도의 조치가 없어도 Position There=Here가 잘 동작하는 것이다.

또한 Class A=B; 식의 선언을 하지 않거나 객체를 함수의 인수로 사용할 일이 전혀 없다는 것이 확실하다면 이때도 복사 생성자가 필요없다. 그러나 이런 가정은 무척 위험할 수 있다. 왜냐하면 클래스의 사용자는 클래스가 일반 타입과 동등하므로 int, double에서 가능한 일들은 클래스에 대해서도 모두 가능하다고 기대하며 실제로 그런 코드를 작성하기 때문이다. 이 기대에 부응하기 위해 클래스는 모든 면에서 기본 타입과 완전히 같아야 한다.

Person2 예제에서 복사 생성자를 정의함으로써 Person 클래스는 이미 생성된 객체로부터 새로운 객체를 선언할 수 있게 되었다. Person 클래스가 점점 기본 타입과 같아지고 있지만 이 클래스는 아직까지도 불완전하다. Person 클래스가 완전한 타입이 되려면 대입 연산자를 재정의해야 하는데 이 실습은 다음에 다시 해 보도록 하자.

출처 : www.winapi.co.kr

설정

트랙백

댓글

new int(3) 과 new int[3]

Programming/C Language 2010. 5. 27. 19:41
계속 C 만 쓰다가 C++ 을 만질 때가 와서 코드를 보다가 순간 동적 할당 문법이 맞나 하는 노파심에 네이버 지식인에 검색을 했는데 아래와 같이 잼있는 질문이 있어서 올린다.

질문

new int(3) 이거하고
new int[3] 이거하고
구체적인 차이가 뭔가요...
좀 갈켜주세요 좀 자세히..


답변
new int(3) 메모리를 int형으로 할당하고 3으로 초기화
new int[3] 메모리를 int형으로 3개 할당. 배열이군요.  


뭐.. 다들 보면 딱 알겠지만 너무 오랜만에 봐서 그런가 어라.. 저게 맞나? 하는 생각도 들었었다 ㅋㅋ 역시 사람의 머리란.. ㅎ C++ 처음부터 공부한다는 생각으로 다시 기본부터 열심히 봐야겠다. ㅎㅎ

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

#if  (0) 2010.05.27
구조체 정렬  (0) 2009.09.27
#include 와 #define 의 순서  (0) 2009.08.18
매크로 함수  (0) 2009.08.18
코딩 스타일  (0) 2009.08.15

설정

트랙백

댓글

[C++] Construct method

Programming/C++ Language 2010. 5. 27. 19:38
Resource leak 을 방지하기 위해, 생성자에서 할당(Allocation) 로직을 빼고, 이를 Construct 함수에 넣자. 즉, 생성자에서는 변수들을 초기화를 하고, Construct 함수를 만들어서 Construct 함수에서 할당 로직을 작성하도록 하자는 것이다. 생성자에 할당(Allocation) 로직을 넣었을 경우, 만에 하나 생성자가 실행 중일 때, 프로그램이 죽을 경우 소멸자가 호출되지 않음으로써 Resource leak 이 발생 할 수 있다.

TestClass::TestClass()
{
__abc = 0;
__pStr = "Test";
}

TestClass::Construct()
{
__ptr = new char( 10 );
}

int main()
{
TestClass Test = new TestClass();
Test.Construct();
return 0;
}


 

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

[C++] Errors : cannot allocate an object of abstract type '???'  (0) 2010.06.14
[C++] 복사 생성자  (0) 2010.05.31
[C++] static_cast  (0) 2010.03.22
[C++] const  (0) 2010.03.19
[C++] 다양한 생성자 초기화 방법  (0) 2010.03.19

설정

트랙백

댓글

#if

Programming/C Language 2010. 5. 27. 17:29

#ifdef, #ifndef는 매크로의 존재 여부만으로 컴파일 조건을 판단하며 매크로가 어떤 값으로 정의되어 있는지는 평가하지 않는다. 이에 비해 #if는 매크로의 값을 평가하거나 여러 가지 조건을 결합하여 컴파일 여부를 결정하는 좀 더 복잡한 전처리문이다. #ifdef보다는 사용법이 조금 까다롭지만 C 언어의 조건문과 유사하므로 쉽게 익힐 수 있다. 기본 형식은 다음과 같다. 

#if 조건1
코드
1           // 조건1을 만족하면 코드1을 컴파일
#elif 조건2
코드
2           // 조건 2가 만족되면 코드2를 컴파일
#else
코드
3           // 둘 다 맞지 않으면 코드 3을 컴파일
#endif

1 ) 매크로값을 비교할 때는 상등, 비교 연산자를 사용한다. 같다, 다르다는 ==, != 연산자를 사용하며 대소를 비교할 때는 >, <, >=, <= 비교 연산자가 사용된다.

#if (LEVEL == 3)
#if (VER >= 7)

조건문은 꼭 괄호로 싸지 않아도 상관없지만 C의 조건문에 익숙한 개발자들은 #if에도 가급적 괄호를 붙여 주는 편이며 괄호가 있는 편이 보기에도 안정감이 느껴져 좋다. #if는 조건문이 참일 때 1로, 거짓일 때 0으로 평가하는데 결과가 0이 아니면 이어지는 코드 블록을 컴파일한다. 이 점도 C와 동일하다.

2 ) 비교 대상은 정수 상수여야 하며 실수나 문자열은 매크로와 비교할 수 없다. 컴파일러에 따라 실수 비교를 허용하는 것들도 있는데 조건부 컴파일을 통제하는 매크로는 대소가 있는 값이라기 보다는 주로 표식이기 때문에 실수는 별로 실용성이 없다고 할 수 있다. 정수값을 가지는 다른 매크로와 값을 비교하는 것은 가능하다.

#if (VER == 3.14)             // 에러
#if (NAME == "Kim")          // 에러
#if (LEVEL == BASIC)       // 가능 

버전 번호 같은 경우에 1.0, 1.5같이 실수로 표기하지만 매크로 상수로 버전을 표시할 때는 100, 150 등과 같이 정수화해서 사용하는 것이 일반적이다.

3 ) 수식 내에서 간단한 사칙 연산을 할 수 있다. 전처리기가 연산문을 평가한 후 그 결과를 비교하므로 다소 복잡한 식은 굳이 결과를 계산해 넣을 필요없이 수식을 바로 써도 상관없다. 

#if (LEVEL*2 == 6)
#if (TIME == 365*24) 

나머지 연산, 비트 연산 등도 가능하다. 그러나 ++, --, 포인터 연산, sizeof, 캐스트 연산 등은 사용할 수 없다. 이런 연산들은 전처리문에서 불가능하거나 의미가 없기 때문이다. 매크로는 상수이므로 좌변값이 아니며 sizeof 연산자는 컴파일시에 평가된다. 전처리는 컴파일 이전의 단계임을 명심하도록 하자.

4 ) 논리 연산자로 두 개 이상의 조건을 동시에 평가할 수 있다. C언어의 논리 연산자와 같은 &&, ||, !를 그대로 사용하면 된다. 

#if (LEVEL == 8 && VER != 3) 

세 개 이상의 조건도 물론 평가할 수 있다. 이때 필요하다면 조건 평가의 우선 순위 지정을 위해 괄호를 사용한다.

5 ) defined 연산자로 매크로의 존재 여부를 평가할 수 있다. #if defined(MACRO) 전처리문은 #ifdef MACRO와 완전히 동일한 문장이다. 그러나 다른 조건과 함께 매크로의 존재 여부를 평가할 때는 #ifdef를 쓸 수 없으므로 defined 연산자가 따로 제공된다. 

#if (LEVEL == 8 || defined(PROFESSIONAL) )

defined 연산자는 전처리문내에서만 사용되므로 일반 C코드에서는 사용할 수 없다.

6 )  #if 다음의 조건부 컴파일 블록에는 어떤 문장이든지 올 수 있다. a=b+c; 연산문이나 함수 호출문, int i; 같은 선언문은 물론이고 struct tag_A { ~ 같은 정의문도 올 수 있다. 심지어 #include, #define같은 다른 전처리문도 조건부 컴파일(정확하게 표현한다면 조건부 전처리) 대상이 될 수 있다. 그렇다면 #if안에 또 다른 #if문이 올 수 있다는 얘기가 되며 즉 #if는 중첩가능한 전처리문이다.

#if (LEVEL == 8)
LEVEL이 8일 때의 코드
#if (VER > 5)
버전이 5보다 클 때의 코드
#endif
LEVEL이 8일 때의 코드
#endif 

#if안에 #ifdef가 올 수도 있고 반대도 가능하며 중첩 깊이에 제한도 없다. 조건속에 또 다른 조건이 있는 것은 자연스러운 것이므로 전처리기는 당연히 조건부 컴파일문의 중첩을 허용한다. 단, 전처리문이 중복될 경우 짝이 되는 #endif가 반드시 존재해야 한다는 것만 주의하면 된다. #endif는 조건부 컴파일 대상의 끝을 명시하는 중요한 역할을 한다. C 코드는 블록이 중첩될 때 적당히 들여쓰기를 하지만 조건부 컴파일 지시자가 중첩될 경우 들여쓰기는 하지 않는 것이 보통이다.

다음은 #if의 활용예를 보자. 어떤 문제를 해결하는데 세 가지(또는 그 이상) 방법이 있고 각 방법을 적용했을 때의 성능을 테스트해 보려고 한다. 이때 각 방법의 코드를 지웠다 넣었다 할 필요없이 다음과 같이 조건부 컴파일문으로 작성해 놓으면 METHOD 매크로만 변경하여 적용할 방법을 쉽게 선택할 수 있다. 이 코드가 다른 프로그램의 부품으로 사용되는 라이브러리이고 고객마다 선호하는 방법이 다르다면 모든 코드를 소스에 둔 채 고객의 주문대로 조건부 컴파일하기만 하면 된다. 

#define METHOD 1
#if (METHOD == 1)
방법1
#elif (METHOD == 2)
방법2
#else
방법3
#endif 

#if 0도 주석 대신 흔히 사용되는 구문이다. 아주 긴 소스를 잠시 주석 처리해 놓고 싶을 때는 이 부분을 #if 0 .... #endif로 감싸 버리면 항상 거짓이므로 전처리기에 의해 이 코드는 없는 것으로 취급된다. /* */ 주석은 중첩될 수 없어 긴 소스를 주석 처리할 때 불편한 반면 #if 0는 중첩 가능하기 때문에 이런 문제가 없다.

출처 : www.winapi.co.kr

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

new int(3) 과 new int[3]  (0) 2010.05.27
구조체 정렬  (0) 2009.09.27
#include 와 #define 의 순서  (0) 2009.08.18
매크로 함수  (0) 2009.08.18
코딩 스타일  (0) 2009.08.15

설정

트랙백

댓글

트랜잭션 [ transaction ] 이란?

Programming/Network 2010. 5. 27. 15:09

①상점에서의 고객의 주문이나 판매, 은행에서의 예금주의 입금이나 출금과 같은 하나의 외부 거래를 기록하기 위해 컴퓨터 시스템 내부에서 완료되어야 하는 일련의 처리 동작. 트랜잭션에는 파일 내용의 갱신, 수신 응답의 통보 등이 포함된다. 트랜잭션 데이터단말기를 통해 입력되는 경우, 하나의 트랜잭션은 단말기와 트랜잭션 응용 프로그램을 작동시키는 컴퓨터 시스템 간의 몇 번의 메시지 교환으로 이루어지기도 한다.
②외부 거래를 기록하기 위해 단말기 등에서 생성하여 컴퓨터 시스템으로 전송되는 데이터. 트랜잭션 데이터와 같은 의미로 사용된다.
데이터베이스에 대한 조회나 갱신 조작의 열로 구성되는 처리의 기본 단위. 갱신에 의해 일시적으로 부정합되는 데이터베이스 내의 데이터가 이용자에게 사용되지 않도록 하기 위해 적절한 구분 기호로 일련의 조작을 한데 묶어서 처리한다. 트랜잭션은 원자성, 정합성, 고립성, 내구성 등의 특성에 의해 실행의 정당성이 보증된다.


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

HTTP and WWW  (0) 2010.08.21
프록시 서버( proxy server )  (0) 2010.08.21
HTTP Method  (0) 2010.06.06
Post/Redirect/Get  (1) 2010.05.31
세션 [ session ] 이란?  (0) 2010.05.27

설정

트랙백

댓글

세션 [ session ] 이란?

Programming/Network 2010. 5. 27. 14:39

①망 환경에서 사용자 간 또는 컴퓨터 간의 대화를 위한 논리적 연결.
②프로세스들 사이에서 통신을 하기 위해 메시지 교환을 통해 서로를 인식한 이후부터 통신을 마칠 때까지의 기간.

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

HTTP and WWW  (0) 2010.08.21
프록시 서버( proxy server )  (0) 2010.08.21
HTTP Method  (0) 2010.06.06
Post/Redirect/Get  (1) 2010.05.31
트랜잭션 [ transaction ] 이란?  (0) 2010.05.27

설정

트랙백

댓글