C를 사용하여 상속을 모델링하려면 어떻게 해야 합니까?
C를 사용하여 상속을 모델링할 수 있습니까? 어떻게요? 샘플 코드가 도움이 될 것입니다.
편집: 데이터와 메서드를 모두 상속받으려고 합니다.컨테이너선만으로는 도움이 되지 않습니다.기본 클래스 개체가 작동하는 파생 클래스 개체를 사용하는 것이 바로 대체 가능성입니다.
이렇게 하는 것은 매우 간단합니다.
struct parent {
int foo;
char *bar;
};
struct child {
struct parent base;
int bar;
};
struct child derived;
derived.bar = 1;
derived.base.foo = 2;
단, MS 확장을 사용하는 경우(GCC 사용 시)-fms-extensions
flag) 어나니머스 네스트 사용 가능struct
그러면 훨씬 좋아집니다.
struct child {
struct parent; // anonymous nested struct
int bar;
};
struct child derived;
derived.bar = 1;
derived.foo = 2; // now it is flat
C는 확실히 오브젝트 지향적인 문체로 쓸 수 있습니다.
캡슐화는 구조 정의를 연관된 헤더가 아닌 .c 파일로 유지함으로써 수행할 수 있습니다.그런 다음 외부 세계는 포인터를 유지함으로써 객체를 처리하며, 사용자는 객체의 "메서드"와 같은 포인터를 받아들이는 함수를 제공합니다.
다형성과 유사한 동작은 함수 포인터를 사용하여 얻을 수 있습니다.이 포인터는 보통 C++ 오브젝트(또는 C++ 오브젝트)의 "가상 메서드 테이블"과 같은 "조작 구조" 내에 그룹화되어 있습니다.ops 구조에는 특정 "하위 클래스"에 고유한 값을 가진 상수 등의 다른 것도 포함될 수 있습니다."상위" 구조에서는 일반적인 운영별 데이터에 대한 참조를 유지할 수 있습니다.void*
포인터물론 "하위 클래스"는 여러 상속 수준에 대해 패턴을 반복할 수 있습니다.
다음 예에서는struct printer
추상 클래스와 비슷하며, 추상 클래스는 입력함으로써 "파생"할 수 있습니다.pr_ops
구조, 생성자 함수 래핑 제공pr_create()
. 각 서브타입은 독자적인 구조를 가지며, 이 구조체는 각 서브타입에 "앵커링"되어 있습니다.struct printer
을 통해 이의를 제기하다data
범용 포인터이것은 에 의해 디멘테이션 됩니다.fileprinter
서브타입.GUI 또는 소켓 기반 프린터를 상상할 수 있습니다. GUI 또는 소켓 기반 프린터는 코드의 나머지 부분에 관계없이struct printer *
언급.
프린터.h:
struct pr_ops {
void (*printline)(void *data, const char *line);
void (*cleanup)(void *data);
};
struct printer *pr_create(const char *name, const struct output_ops *ops, void *data);
void pr_printline(struct printer *pr, const char *line);
void pr_delete(struct printer *pr);
printer.c:
#include "printer.h"
...
struct printer {
char *name;
struct pr_ops *ops;
void *data;
}
/* constructor */
struct printer *pr_create(const char *name, const struct output_ops *ops, void *data)
{
struct printer *p = malloc(sizeof *p);
p->name = strdup(name);
p->ops = ops;
p->data = data;
}
void pr_printline(struct printer *p, const char *line)
{
char *l = malloc(strlen(line) + strlen(p->name) + 3;
sprintf(l, "%s: %s", p->name, line);
p->ops->printline(p->data, l);
}
void pr_delete(struct printer *p)
{
p->ops->cleanup(p->data);
free(p);
}
마지막으로 fileprinter.c:
struct fileprinter {
FILE *f;
int doflush;
};
static void filepr_printline(void *data, const char *line)
{
struct fileprinter *fp = data;
fprintf(fp->f, "%s\n", line);
if(fp->doflush) fflush(fp->f);
}
struct printer *filepr_create(const char *name, FILE *f, int doflush)
{
static const struct ops = {
filepr_printline,
free,
};
struct *fp = malloc(sizeof *fp);
fp->f = f;
fp->doflush = doflush;
return pr_create(name, &ops, fp);
}
예, "type punning" 기술을 사용하여 유전율을 에뮬레이트할 수 있습니다.이는 파생 클래스 내의 베이스 클래스(구조) 선언이며 파생된 것을 베이스로 캐스팅합니다.
struct base_class {
int x;
};
struct derived_class {
struct base_class base;
int y;
}
struct derived_class2 {
struct base_class base;
int z;
}
void test() {
struct derived_class d;
struct derived_class2 d2;
d.base.x = 10;
d.y = 20;
printf("x=%i, y=%i\n", d.base.x, d.y);
}
그러나 파생된 것을 프로그램에서 베이스로 캐스팅하려면 파생 구조의 첫 번째 위치에 베이스 클래스를 선언해야 합니다.
struct base *b1, *b2;
b1 = (struct base *)d;
b2 = (struct base *)d2;
b1->x=10;
b2->x=20;
printf("b1 x=%i, b2 x=%i\n", b1->x, b2->x);
이 스니펫에서는 기본 클래스만 사용할 수 있습니다.
프로젝트에서는 oop4c라는 기술을 사용하고 있습니다.
적어도 어느 정도는 가능해야 한다.
구체적으로 어떤 모델이 필요합니까?데이터 상속 또는 방법 상속?
편집: 여기 제가 찾은 짧은 기사가 있습니다.http://fluff.info/blog/arch/00000162.htm
나는 C의 객체 시스템을 사용해 본 적이 있다.늦은 바운드의 방법을 사용하여 반사된 객체 지향성을 가능하게 한다.
여기서 보실 수 있습니다.
#include <stdio.h>
///////Class Cobj
typedef struct Cobj{
int x;
void (*setptr)(char * s,int val);
int (*getptr)(char * s);
} Cobj;
void set(char * s,int val)
{
Cobj * y=(Cobj *)s;
y->x=val;
}
int get(char * s){
Cobj * y=(Cobj *)s;
return y->x;
}
///////Class Cobj
Cobj s={12,set,get};
Cobj x;
void main(void){
x=s;
x.setptr((char*)&x,5);
s.setptr((char*)&s,8);
printf("%d %d %d",x.getptr((char*)&x),s.getptr((char*)&s) ,sizeof(Cobj));
}
이 링크는 도움이 될 수 있습니다.-> 링크
기본적인 예는 다음과 같습니다.
struct BaseStruct
{
// some variable
}
struct DerivedStruct
{
struct BaseStruct lw;
// some more variable
};
언급URL : https://stackoverflow.com/questions/1237266/how-can-inheritance-be-modelled-using-c
'programing' 카테고리의 다른 글
Vue Draggable 이전 목록으로 이동 (0) | 2022.08.08 |
---|---|
Vue js vee의 암호 확인은 항상 false (0) | 2022.08.08 |
Linux에서 여러 스레드를 사용한 신호 처리 (0) | 2022.08.08 |
VueJ 컴포넌트 간에 데이터를 공유하는 방법s (0) | 2022.08.08 |
vue.timeout - v-timeout 대체 (0) | 2022.08.08 |