2011-10-19 5 views
0

C에서 C로 코드를 변환하는 중입니다. C에서 Object factory에 해당하는 패턴이 있습니까?C++ 대신 C 객체 팩터얼

다음 소스 코드를 고려하십시오. 매개 변수 (int type)를 기반으로 ObjectFactory() 함수는 페디큐어 유형의 구조체에 대한 void 포인터를 반환해야합니다. 어떻게 함수를 반환 한 후 포인터를 가질 수있는 방식으로 구조체를 인스턴스화 할 수 있습니다.

typedef struct { 
    unsigned int a; 
    unsigned int b; 
    unsigned int c; 
} CThings ; 

typedef struct { 
    unsigned int d; 
    unsigned int e; 
    unsigned int f; 
} CPlaces ; 

void * ObjectFactory(int type) { 

    switch(type) { 
     case 5 : {   
      return ??? CPlaces ; 
      break; 
     } 
     case 35 : {   
      return ??? CThings ; 
      break; 
     } 
     default: { 
      // unknown type 
      return NULL ; 
     } 
    } 

    return NULL ; 
} 



int _tmain(int argc, _TCHAR* argv[]) 
{ 
    void * p = ObjectFactory(5); 

    // Do soemthing with the pointer. 
    CPlaces * places = (CPlaces*) p ; 

    places->d = 5 ; 
    places->e = 6 ; 
    places->f = 7 ; 


    return 0; 
} 
+4

이것은 C++에서 C 로의 변환으로, 특히 눈에 띄지 않는 것 같습니다. 분명히 무의미한 활동에 참여한 이유를 설명해 주시겠습니까? –

+2

@ AlfP.Steinbach +1 : 당신이 쓴 최고의 코멘트. –

+0

'return (void *) new CPlaces(); ' –

답변

5

어떻게 malloc 사용에 대한 :

case 5: return malloc(sizeof(struct CPlaces)); 

필요 없음을 break 당신이 이미 반환합니다. 원하는 경우 초기화하기 전에 초기화를 추가 할 수 있습니다.

호출자는 포인터를 올바른 유형으로 다시 캐스트 할 수 있도록 실제 유형을 알아야합니다. 이것은 아마도 발신자 사이트에서 중복 된 switch 문에 해당합니다.

0
#include <stdlib.h> 

typedef enum enum_ObjectType { 
    CPlaces_Object = 5, 
    CThings_Object = 35, 
} ObjectType; 

typedef struct struct_CThings { 
    unsigned int a; 
    unsigned int b; 
    unsigned int c; 
} CThings; 

typedef struct struct_CPlaces { 
    unsigned int d; 
    unsigned int e; 
    unsigned int f; 
} CPlaces ; 

void *ObjectFactory(ObjectType type) { 
    switch(type) { 
     case CPlaces_Object: { 
      return malloc(sizeof(CPlaces)); 
      break; 
     } 
     case CThings_Object: { 
      return malloc(sizeof(CThings)); 
      break; 
     } 
     default: { /* unknown type */ 
      return NULL; 
     } 
    } 
    return NULL; 
} 

int main(void) { 
    CPlaces *places = ObjectFactory(CPlaces_Object); 
    CThings *things = ObjectFactory(CThings_Object); 

    things->a = 2; 
    things->b = 8; 
    things->c = 4; 

    places->d = 5; 
    places->e = 7; 
    places->f = 3; 

    return 0; 
} 
+0

아쉽게도 이는 C++ 객체 팩토리와 완전히 동일하지 않습니다. 내 객체가 쓰레기가 아닌 다른 것으로 초기화 될 것으로 기대됩니다. 나는 varargs 매개 변수를 가져 와서 malloc 및 초기화를 감싸는 "생성자"기능을 갖도록 제안합니다. 이러한 생성자는 varargs를 가져오고 varargs의 압축을 푼 후에 "실제"생성자를 호출하도록 오버로드 될 수 있습니다. –

+0

varargs를 사용하지 마십시오. 형식이 실제로 관련되어 있고 팩터를 만드는 것이 타당한 경우 논리적으로 공통 인수 집합을 사용하여 형식을 생성 할 수 있어야합니다. 즉, varargs를 사용하면 기본적으로 어쨌든 전달되는 생성자를 알아야하기 때문에 우리가 만드는 유형을 알아야한다는 것을 의미하므로 직접 만들 수도 있습니다. –

+0

@Michael Price, malloc 대신 임의의 쓰레기 호출 calloc을 원하지 않는 경우 D –