안녕하세요, 저는 C++ 프로그램을 C로 이식하고 있습니다. C에서 structs를 사용하여 C++ 클래스에서 상속을 시뮬레이션 할 때 다음 코드를 사용하고 있습니다.C "시뮬레이션 된 상속"동안 다른 구조체 포인터 사이에 캐스팅
typedef struct GenTask GenTask;
typedef struct Task Task;
typedef struct UserTask UserTask;
struct GenTask{
char name[MAXCHAR];
boolean isUserTask;
int k;
void (*print)(Task*);
};
GenTask* newGenTask(const char* n){
GenTask* inhTask = (GenTask*)malloc(sizeof(GenTask));
strncpy(inhTask->name, n, MAXCHAR);
inhTask->k = 1;
return inhTask;
}
struct Task{
GenTask* inhTask;
};
void printTask(Task* task){
printf("\nThis is Task: %s",task->inhTask->name);
}
Task* newTask(const char* n){
Task* task = (Task*)malloc(sizeof(Task));
task->inhTask = newGenTask(n);
task->inhTask->isUserTask = false;
task->inhTask->print = printTask;
return task;
}
void deleteTask(Task* task){
free(task->inhTask);
free(task);
}
struct UserTask{
GenTask* inhTask;
int m;
};
void printUserTask(Task* task){
UserTask* ut = (UserTask*)task;
printf("\nThis is UserTask nbr: %d",ut->m);
}
UserTask* newUserTask(const char* n){
UserTask *ut = (UserTask*)malloc(sizeof(UserTask));
ut->inhTask = newGenTask(n);
ut->inhTask->isUserTask = true;
ut->inhTask->print = printUserTask;
ut->m=100;
return ut;
}
void deleteUserTask(UserTask* utask){
free(utask->inhTask);
free(utask);
}
코드 실행을 시도했는데 예상대로 작동합니다 (또는 작동하기를 바랍니다).). 내 질문에, 만약 여분의 "UserTask-memory"가 아래와 같이 타입 캐스팅 후에 노출 될 위험이 있다면 그렇습니다.
Task* task = (Task*)newUserTask("A UserTask");
UserTask 포인터로 다시 캐스트 할 때 아무런 문제가없는 것처럼 보입니다.
UserTask* utask = (UserTask*)task;
내가 생각하는 나는 "A UserTask"무료 utask 및 사용 deleteUserTask (utask)에, I suffies에 대한 메모리를 해제 할 때? 대신 deleteTask (task)를 사용하여 자유 태스크를 사용하면 UserTask 특정 메모리가 해제되지 않는다고 생각합니다.
저는 C++과 C 모두에게 새로운 기능을 제공합니다. 이전에는 Java를 사용했고 동적 메모리 할당은 여전히 약간 무서웠습니다 ... 어떤 도움을 주셔서 감사합니다!
/패트릭
예 나는 그것을 또한 보았다. 내가 그렇게하지 않은 이유는 GenTask-struct가 (구현에서) 포인터를 포함하고 있기 때문에 어떻게 든 그 메모리를 해제해야만합니다. 하지만 그래, 나는 여전히 포인터로 사용하는 것이 다소 희박하다는 것을 알 수있다. 그걸 바꿀 수도 있어요. 하지만 "작업 구조체에 대한 포인터가 작업 *에 캐스트 될 수 있습니다"라는 의미에서 "작업"에 의해 명시 적으로 의미하는 것은 무엇입니까? GenTask가있는 구조체는 무엇입니까? 답장을 보내 주셔서 감사합니다 –
만약 당신이 Task *를 가지고 있다면, 명시 적으로 역 참조하는 대신 투명하게 GenTask *로 취급 할 수 있습니다. GenTask *에 구조체를 삭제할 때 해제해야하는 메모리 포인터가 있으면 모든 '하위 구조체'에 대해서도이를 수행해야합니다. –