Turbo-C
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
터보-C 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
Lua 게시판
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C/C++ Q/A
[1761] 캐스팅 그리고 포인터에 대한 질문.
goodlsw [] 1392 읽음    2003-01-01 16:44
예전에 어느 사이트에서 빼온 객체와 포인터에 대한 예제입니다.


제가 struct _mankind 구조체에서 Object  object;를 빼고 돌렸을 경우.

그래도 동일한 결과가 나오더군요.(전 에러가 나는 줄 알았거든요.)

만일 뺐을경우, creat 함수 부분에서 Object *mankind = (Object *)malloc( sizeof(Mankind) );

에서는 어떻게 처리되는거죠? 할당된 메모리값은 1바이트이고,

그상태에서 다시 object형으로 캐스팅 되었는데 그럼 *mankind는 어떻게 받아들여지는거죠?

여기서 아주 혼란스럽네요. 도움 바랍니다.
--------------------------------------------------------------------------------
#include <stdio.h>
  #include <stdlib.h> /* malloc(), free() */
  #include <string.h> /* strlen(), strcpy() */

  /* 구조체를 타입에 맞게 캐스팅 해주는 매크로 함수 */
  #define OBJECT(object)  ((Object *)(object))
  #define MANKIND(object) ((Mankind *)(object))

  typedef struct _object  Object;
  typedef struct _mankind Mankind;

  typedef enum _type      Type;

  enum _type
  {
      OBJECT_TYPE,        /* 객체(Object) 타입  */
      MANKIND_TYPE        /* 사람(Mankind) 타입 */
  };

  struct _object
  {
      Type            type;   /* 객체의 종류      */
      unsigned long   ID;     /* 객체의 일련 번호 */
  };

  struct _mankind
  {
      Object  object;     /* 객체(Object) 속성 상속 */
      char *  name;       /* 이름                   */
  };

  /* 객체의 일련번호 부여를 위한 전역 변수 */
  unsigned long _objectID = 0;

  /*
   * 함수의 원형(prototype) 선언
   */
  void            setObjectID( Object *object );
  unsigned long   getObjectID( Object *object );
  void            setObjectType( Object *object, Type type );
  Type            getObjectType( Object *object );
  void            freeObject( Object *object );

  Object *    createMankind(void);
  void        setMankindName( Mankind *mankind, char *name );
  char *      getMankindName( Mankind *mankind );
  void        freeMankind( Mankind *mankind );

  /* setObjectID
   *
   * 객체의 고유 일련번호를 설정한다.
   * 이 함수는 사용자가 마음대로 사용할 목적이 아니라,
   * 객체가 생성되었을 때 한번 호출해서 객체에게 일련번호를
   * 부여하는 것이다.
   *
   * 전역변수인 _objectID은 객체에게 일련번호를 부여하고 난 후,
   * 1씩 증가한다.
   */
  void setObjectID( Object *object )
  {
      object->ID = _objectID++;
  }

  /* getObjectID
   *
   * 객체의 고유 일련번호(ID)를 구한다.
   */
  unsigned long getObjectID( Object *object )
  {
      return object->ID;
  }

  /* setObjectType
   *
   * 객체의 타입을 설정한다.
   */
  void setObjectType( Object *object, Type type )
  {
      object->type = type;
  }

  /* getObjectType
   *
   * 객체의 type을 구한다.
   * 객체의 type은 객체의 특성을 말한다.
   *
   * 객체 생성함수에 따라서 그 객체의 type은 설정된다.
   */
  Type getObjectType( Object *object )
  {
      return object->type;
  }

  /* freeObject
   *
   * 생성된 객체의 할당받은 메모리를 해제한다.
   * Object의 type을 조사하여 각 type에 맞는 해제 함수를 호출한다.
   */
  void freeObject( Object *object )
  {
      /* 해제시킬 객체의 종류를 알아낸다. */
      Type type = getObjectType(object);

      /* 종류에 맞는 파괴 함수를 호출 */
      switch( type )
      {
          case OBJECT_TYPE :
              break;
          case MANKIND_TYPE :
              freeMankind( MANKIND(object) ); break;
      }

      /* 마지막으로 각 type의 크기만큼 할당된 메모리를 해제한다. */
      free( object );
  }

  /* createMankind
   *
   * 사람 객체를 생성하는 함수이다.
   *
   * 모든 객체는 create*() 함수로 생성되어지며, 그 객체의 데이터 형은
   * Object * 이다.
   * 모든 객체의 구조체 타입이 다 다르지만 Object 구조체로 모든 객체를
   * 다룰 수 있도록 하기 위해서 메모리는 sizeof(Mankind) 만큼 할당되지만
   * 그 할당 받은 메모리를 (Object *)로 캐스팅한다.
   *
   * 그렇다고 해서 할당받은 메모리의 크기가 변한다던지 하는게 아니라
   * 단지 그 할당받은 메모리를 참조하기 위한 index로 Object 구조체를
   * 사용하겠다는 것만 알려주는 것일 뿐이다.
   *
   * 실제로 Mankind 구조체에 있는 속성을 사용하기 위해서,
   * (object *)로 캐스팅된 메모리는 다시 (Mankind *)로 캐스팅되야 한다.
   * MANKIND(object) 매크로 함수를 사용해도 된다.
   *
   * 이렇게 캐스팅을 통해서,
   * 많은 종류의 객체들을 대표적인 객체 제어 함수로 제어를 할 수 있게 된다.
   * 예를 들면 어떤 타입의 객체라도 freeObject() 함수로 파괴를 할 수가
   * 있게 되는 것이다.
   */
  Object *createMankind(void)
  {
      /* Mankind 구조체 크기 만큼의 메모리를 할당 받은 후
       * (Object *)로 캐스팅 한다.
       */
      Object *mankind = (Object *)malloc( sizeof(Mankind) );
      if( mankind == NULL ) return NULL;

      /* 할당받은 메모리를 0으로 초기화 한다. */
      memset( mankind, 0, sizeof(Mankind) );

      /* 생성된 객체의 type을 MANKIND_TYPE으로 설정한다.
       * 즉, 이 객체는 사람 객체임을 뜻한다.
       */
      setObjectType( mankind, MANKIND_TYPE );

      /* 생성된 객체의 고유 일련번호를 부여한다. */
      setObjectID( mankind );

      return mankind;
  }

  /* setMankindName
   *
   * 사람 객체의 이름 속성을 설정한다.
   */
  void setMankindName( Mankind *mankind, char *name )
  {
      /* name 인자의 문자열 길이 + 1 만큼 메모리를 할당한다.
       * 1을 더하는 이유는 문자열 마지막에 NULL을 저장하기 위함이다.
       */
      mankind->name = (char *)malloc( strlen(name) + 1 );
      if( mankind->name == NULL ) return;

      /* 사람 객체의 이름 속성에 name 을 복사한다. */
      strcpy( mankind->name, name );
  }

  /* getMankindName
   *
   * 사람 객체의 이름 속성을 구한다.
   */
  char *getMankindName( Mankind *mankind )
  {
      return mankind->name;
  }

  /* freeMankind
   *
   * 사람 객체의 속성을 해제하는 파괴함수.
   */
  void freeMankind( Mankind *mankind )
  {
      /* 사람 이름 속성 해제 */
      if( mankind->name != NULL )
          free( mankind->name );
  }

  int main(void)
  {
      Object *man = NULL;

      man = createMankind();
      setMankindName( MANKIND(man), "Shim sang don" );

      printf("Man ID = %ld, name = %s\n",
              getObjectID(man), getMankindName( MANKIND(man) ) );

      freeObject(man);

      return 0;
  }

+ -

관련 글 리스트
1761 캐스팅 그리고 포인터에 대한 질문. goodlsw 1392 2003/01/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.