programing

C를 사용하여 상속을 모델링하려면 어떻게 해야 합니까?

luckcodes 2022. 8. 8. 22:13

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-extensionsflag) 어나니머스 네스트 사용 가능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