C语言中的结构继承

C语言中的结构继承,c,structure,C,Structure,我可以继承C语言中的结构吗?如果是,怎么做?不,您不能。C不支持继承的概念 > P> C不是面向对象语言,因此没有继承性。 可以模拟它,但不能真正继承。 < P> C没有明确的继承概念,不像C++。但是,您可以在另一个结构中重用一个结构: typedef struct { char name[NAMESIZE]; char sex; } Person; typedef struct { Person person; char job[JOBSIZE]; } Em

我可以继承C语言中的结构吗?如果是,怎么做?

不,您不能。C不支持继承的概念

> P> C不是面向对象语言,因此没有继承性。

可以模拟它,但不能真正继承。

< P> C没有明确的继承概念,不像C++。但是,您可以在另一个结构中重用一个结构:

typedef struct {
    char name[NAMESIZE];
    char sex;
} Person;

typedef struct {
    Person person;
    char job[JOBSIZE];
} Employee;

typedef struct {
    Person person;
    char booktitle[TITLESIZE];
} LiteraryCharacter;
不,你不能。
在我看来,在C语言中实现OOP的最佳方法是使用。

最接近的是一个相当常见的习惯用法:

typedef struct
{
    // base members

} Base;

typedef struct
{
    Base base;

    // derived members

} Derived;
由于
派生的
基的副本开始,因此可以执行以下操作:

Base *b = (Base *)d;
typedef struct Base
{
    // base members
} Base_t;

typedef struct
{
   struct Base;  //anonymous struct

   // derived members

} Derived_t;
其中
d
派生的
的实例。所以它们是多态的。但是拥有虚拟方法是另一个挑战——要做到这一点,您需要在
Base
中有一个vtable指针,其中包含指向接受
Base
作为其第一个参数的函数的函数指针(您可以将其命名为
this


P> >你也可以使用C++!p> 您可以执行上述操作

typedef struct
{
    // base members

} Base;

typedef struct
{
    Base base;

    // derived members

} Derived;

但是,如果您想避免指针强制转换,可以使用指向
派生的
联合
的指针,我喜欢并使用了

例如:

struct Animal
{
    int weight;
};

struct Felidae
{
    union {
      struct Animal animal;
    } base;
    int furLength;
};

struct Leopard
{
    union {
      struct Animal animal;
      struct Felidae felidae;
    } base;

    int dotCounter;
};
用法:

struct Leopard leopard;
leopard.base.animal.weight = 44;
leopard.base.felidae.furLength = 2;
leopard.dotCounter = 99;

如果编译器支持匿名结构,则可以执行以下操作:

Base *b = (Base *)d;
typedef struct Base
{
    // base members
} Base_t;

typedef struct
{
   struct Base;  //anonymous struct

   // derived members

} Derived_t;

通过这种方式,可以直接访问基本stuct成员,这会更好。

如果您想使用一些gcc魔术(我假设它可以与Microsoft的C编译器一起使用),您可以执行以下操作:


struct A
{
   int member1;
};

struct B
{
   struct A;
   int member2;
}
使用gcc,您可以使用-fms扩展来编译它(允许像Microsofts编译器那样使用未命名的结构成员)。这与Daniel Earwicker给出的解决方案类似,只是它允许您在结构B实例上访问memeber1。i、 e B.member1而不是B.A.member1

这可能不是最便携的方法,如果使用C++编译器(不同的语言语义意味着它是重新声明/定义结构A而不是实例化它),那么它将不起作用。


然而,如果你生活在gcc/C土地上,它只会工作,做你想做的事。

anon(和其他人的类似说法)的答案略有不同。对于一级深度继承,可以执行以下操作:

#define BASEFIELDS              \
    char name[NAMESIZE];        \
    char sex

typedef struct {
    BASEFIELDS;
} Person;

typedef struct {
    BASEFIELDS;
    char job[JOBSIZE];
} Employee;

typedef struct {
    BASEFIELDS;
    Employee *subordinate;
} Manager;
这样,接受指向人员的指针的函数将接受指向员工或经理的指针(带转换),与其他答案相同,但在这种情况下,初始化也将是自然的:

Employee e = {
    .name = "...";
    ...
};
vs

我相信这就是一些流行的项目是如何做到这一点的(例如libuv)


更新:在使用结构和联合的libsdl事件实现中,也有一些类似(但不相同)概念的好例子。

这适用于使用-fms扩展编译

main.c

#include "AbstractProduct.h"
#include "Book.h"
#include "Product.h"
#include "TravelGuide.h"

/***********************/

int main() {

    Product p = Product_new();  
    p.set_id(&p, 2);
    p.set_name(&p, "name2");
    p.set_description(&p, "description2");
    p.set_price(&p, 2000);  
    p.display(&p);

    TravelGuide tg = TravelGuide_new(); 
    tg.set_id(&tg, 1);
    tg.set_name(&tg, "name1");
    tg.set_description(&tg, "description1");        
    tg.set_price(&tg, 1000);
    tg.set_isbn(&tg, "isbn1");
    tg.set_author(&tg, "author1");
    tg.set_title(&tg, "title1");
    tg.set_country(&tg, "country1");
    tg.display(&tg);

}
#include "AbstractProduct.h"

/*-------------------------------*/

static void set_id(AbstractProduct *this, int id) {
    this->id = id;
}

/*-------------------------------*/

static void set_name(AbstractProduct *this, char *name) {
    strcpy(this->name, name);
}

/*-------------------------------*/

static void set_description(AbstractProduct *this, char *description) {
    strcpy(this->description, description);
}

/*-------------------------------*/

static int get_id(AbstractProduct *this) {
    return this->id;    
}

/*-------------------------------*/

static char *get_name(AbstractProduct *this) {
    return this->name;  
}

/*-------------------------------*/

static char *get_description(AbstractProduct *this) {
    return this->description;   
}

/*-------------------------------*/

static void display(AbstractProduct *this) {

    printf("-AbstractProduct- \n"); 
    printf("id: %d\n", this->get_id(this)); 
    printf("name: %s\n", this->get_name(this)); 
    printf("description: %s\n", this->get_description(this));   
    printf("\n");
}

/*-------------------------------*/

void AbstractProduct_init(AbstractProduct *obj) {

    obj->set_id = set_id;
    obj->set_name = set_name;
    obj->set_description = set_description; 
    obj->get_id = get_id;
    obj->get_name = get_name;
    obj->get_description = get_description;
    obj->display = display;

}

/*-------------------------------*/

AbstractProduct AbstractProduct_new() {

    AbstractProduct aux;
    AbstractProduct_init(&aux);
    return aux;
}
#include "Book.h"

/*-------------------------------*/

static void set_isbn(Book *this, char *isbn) {
    strcpy(this->isbn, isbn);
}

/*-------------------------------*/

static void set_author(Book *this, char *author) {
    strcpy(this->author, author);
}

/*-------------------------------*/

static void set_title(Book *this, char *title) {
    strcpy(this->title, title);
}

/*-------------------------------*/

static char *get_isbn(Book *this) {
    return this->isbn;  
}

/*-------------------------------*/

static char *get_author(Book *this) {
    return this->author;    
}

/*-------------------------------*/

static char *get_title(Book *this) {
    return this->title; 
}

/*-------------------------------*/

static void display(Book *this) {

    Product p = Product_new();
    p.display(this);    

    printf("-Book- \n");
    printf("isbn: %s\n", this->get_isbn(this)); 
    printf("author: %s\n", this->get_author(this)); 
    printf("title: %s\n", this->get_title(this));   
    printf("\n");
}

/*-------------------------------*/

void Book_init(Book *obj) {

    Product_init((Product*)obj);

    obj->set_isbn = set_isbn;
    obj->set_author = set_author;
    obj->set_title = set_title; 
    obj->get_isbn = get_isbn;
    obj->get_author = get_author;
    obj->get_title = get_title; 
    obj->display = display;
}
/*-------------------------------*/

Book Book_new() {

    Book aux;   
    Book_init(&aux);
    return aux;
}
#include "Product.h"

/*-------------------------------*/

static void set_price(Product *this, double price) {
    this->price = price;
}

/*-------------------------------*/

static double get_price(Product *this) {
    return this->price; 
}

/*-------------------------------*/

static void display(Product *this) {

    AbstractProduct p = AbstractProduct_new();
    p.display(this);    

    printf("-Product- \n"); 
    printf("price: %f\n", this->get_price(this));   
    printf("\n");
}

/*-------------------------------*/

void Product_init(Product *obj) {

    AbstractProduct_init((AbstractProduct*)obj);

    obj->set_price = set_price;
    obj->get_price = get_price; 
    obj->display = display;

}

/*-------------------------------*/

Product Product_new() {

    Product aux;    
    Product_init(&aux);
    return aux;
}
#include "TravelGuide.h"

/*-------------------------------*/

static void set_country(TravelGuide *this, char *country) {
    strcpy(this->country, country);
}

/*-------------------------------*/

static char *get_country(TravelGuide *this) {
    return this->country;   
}

/*-------------------------------*/

static void display(TravelGuide *this) {

    Book b = Book_new();
    b.display(this);

    printf("-TravelGuide- \n"); 
    printf("country: %s\n", this->get_country(this));   
    printf("\n");
}

/*-------------------------------*/

void TravelGuide_init(TravelGuide *obj) {

    Book_init((Book*)obj);
    obj->set_country = set_country;
    obj->get_country = get_country;
    obj->f = obj->display;
    obj->display = display;

}

/*-------------------------------*/

TravelGuide TravelGuide_new() {

    TravelGuide aux;
    TravelGuide_init(&aux);
    return aux;
}
AbstractProduct.c

#include "AbstractProduct.h"
#include "Book.h"
#include "Product.h"
#include "TravelGuide.h"

/***********************/

int main() {

    Product p = Product_new();  
    p.set_id(&p, 2);
    p.set_name(&p, "name2");
    p.set_description(&p, "description2");
    p.set_price(&p, 2000);  
    p.display(&p);

    TravelGuide tg = TravelGuide_new(); 
    tg.set_id(&tg, 1);
    tg.set_name(&tg, "name1");
    tg.set_description(&tg, "description1");        
    tg.set_price(&tg, 1000);
    tg.set_isbn(&tg, "isbn1");
    tg.set_author(&tg, "author1");
    tg.set_title(&tg, "title1");
    tg.set_country(&tg, "country1");
    tg.display(&tg);

}
#include "AbstractProduct.h"

/*-------------------------------*/

static void set_id(AbstractProduct *this, int id) {
    this->id = id;
}

/*-------------------------------*/

static void set_name(AbstractProduct *this, char *name) {
    strcpy(this->name, name);
}

/*-------------------------------*/

static void set_description(AbstractProduct *this, char *description) {
    strcpy(this->description, description);
}

/*-------------------------------*/

static int get_id(AbstractProduct *this) {
    return this->id;    
}

/*-------------------------------*/

static char *get_name(AbstractProduct *this) {
    return this->name;  
}

/*-------------------------------*/

static char *get_description(AbstractProduct *this) {
    return this->description;   
}

/*-------------------------------*/

static void display(AbstractProduct *this) {

    printf("-AbstractProduct- \n"); 
    printf("id: %d\n", this->get_id(this)); 
    printf("name: %s\n", this->get_name(this)); 
    printf("description: %s\n", this->get_description(this));   
    printf("\n");
}

/*-------------------------------*/

void AbstractProduct_init(AbstractProduct *obj) {

    obj->set_id = set_id;
    obj->set_name = set_name;
    obj->set_description = set_description; 
    obj->get_id = get_id;
    obj->get_name = get_name;
    obj->get_description = get_description;
    obj->display = display;

}

/*-------------------------------*/

AbstractProduct AbstractProduct_new() {

    AbstractProduct aux;
    AbstractProduct_init(&aux);
    return aux;
}
#include "Book.h"

/*-------------------------------*/

static void set_isbn(Book *this, char *isbn) {
    strcpy(this->isbn, isbn);
}

/*-------------------------------*/

static void set_author(Book *this, char *author) {
    strcpy(this->author, author);
}

/*-------------------------------*/

static void set_title(Book *this, char *title) {
    strcpy(this->title, title);
}

/*-------------------------------*/

static char *get_isbn(Book *this) {
    return this->isbn;  
}

/*-------------------------------*/

static char *get_author(Book *this) {
    return this->author;    
}

/*-------------------------------*/

static char *get_title(Book *this) {
    return this->title; 
}

/*-------------------------------*/

static void display(Book *this) {

    Product p = Product_new();
    p.display(this);    

    printf("-Book- \n");
    printf("isbn: %s\n", this->get_isbn(this)); 
    printf("author: %s\n", this->get_author(this)); 
    printf("title: %s\n", this->get_title(this));   
    printf("\n");
}

/*-------------------------------*/

void Book_init(Book *obj) {

    Product_init((Product*)obj);

    obj->set_isbn = set_isbn;
    obj->set_author = set_author;
    obj->set_title = set_title; 
    obj->get_isbn = get_isbn;
    obj->get_author = get_author;
    obj->get_title = get_title; 
    obj->display = display;
}
/*-------------------------------*/

Book Book_new() {

    Book aux;   
    Book_init(&aux);
    return aux;
}
#include "Product.h"

/*-------------------------------*/

static void set_price(Product *this, double price) {
    this->price = price;
}

/*-------------------------------*/

static double get_price(Product *this) {
    return this->price; 
}

/*-------------------------------*/

static void display(Product *this) {

    AbstractProduct p = AbstractProduct_new();
    p.display(this);    

    printf("-Product- \n"); 
    printf("price: %f\n", this->get_price(this));   
    printf("\n");
}

/*-------------------------------*/

void Product_init(Product *obj) {

    AbstractProduct_init((AbstractProduct*)obj);

    obj->set_price = set_price;
    obj->get_price = get_price; 
    obj->display = display;

}

/*-------------------------------*/

Product Product_new() {

    Product aux;    
    Product_init(&aux);
    return aux;
}
#include "TravelGuide.h"

/*-------------------------------*/

static void set_country(TravelGuide *this, char *country) {
    strcpy(this->country, country);
}

/*-------------------------------*/

static char *get_country(TravelGuide *this) {
    return this->country;   
}

/*-------------------------------*/

static void display(TravelGuide *this) {

    Book b = Book_new();
    b.display(this);

    printf("-TravelGuide- \n"); 
    printf("country: %s\n", this->get_country(this));   
    printf("\n");
}

/*-------------------------------*/

void TravelGuide_init(TravelGuide *obj) {

    Book_init((Book*)obj);
    obj->set_country = set_country;
    obj->get_country = get_country;
    obj->f = obj->display;
    obj->display = display;

}

/*-------------------------------*/

TravelGuide TravelGuide_new() {

    TravelGuide aux;
    TravelGuide_init(&aux);
    return aux;
}
AbstractProduct.h

#ifndef AbstractProduct_H
#define AbstractProduct_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/***********************/

typedef struct AbstractProduct{

    int id;
    char name[1000];
    char description[1000];

    void (*set_id)();
    void (*set_name)();
    void (*set_description)();  
    int (*get_id)();    
    char *(*get_name)();    
    char *(*get_description)(); 
    void (*display)();  

} AbstractProduct;

AbstractProduct AbstractProduct_new();
void AbstractProduct_init(AbstractProduct *obj);

#endif
#ifndef Book_H
#define Book_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Product.h"

/***********************/

typedef struct Book{

    Product;
    char isbn[1000];
    char author[1000];
    char title[1000];

    void (*set_isbn)();
    void (*set_author)();
    void (*set_title)();    

    char *(*get_isbn)();
    char *(*get_author)();
    char *(*get_title)();   
    // void (*display)();   


} Book;

Book Book_new();
void Book_init(Book *obj);

#endif
#ifndef Product_H
#define Product_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AbstractProduct.h"

/***********************/

typedef struct Product{

    AbstractProduct;
    double price;

    void (*set_price)();
    double (*get_price)();  
    // void (*display)();   

} Product;

Product Product_new();
void Product_init(Product *obj);

#endif
#ifndef TravelGuide_H
#define TravelGuide_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Book.h"

/***********************/

typedef struct TravelGuide{

    Book;
    char country[1000];
    void (*f)();

    void (*set_country)();
    char *(*get_country)();
    // void *(*display)();

} TravelGuide;

TravelGuide TravelGuide_new();
void TravelGuide_init(TravelGuide *obj);

#endif
Book.h

#ifndef AbstractProduct_H
#define AbstractProduct_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/***********************/

typedef struct AbstractProduct{

    int id;
    char name[1000];
    char description[1000];

    void (*set_id)();
    void (*set_name)();
    void (*set_description)();  
    int (*get_id)();    
    char *(*get_name)();    
    char *(*get_description)(); 
    void (*display)();  

} AbstractProduct;

AbstractProduct AbstractProduct_new();
void AbstractProduct_init(AbstractProduct *obj);

#endif
#ifndef Book_H
#define Book_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Product.h"

/***********************/

typedef struct Book{

    Product;
    char isbn[1000];
    char author[1000];
    char title[1000];

    void (*set_isbn)();
    void (*set_author)();
    void (*set_title)();    

    char *(*get_isbn)();
    char *(*get_author)();
    char *(*get_title)();   
    // void (*display)();   


} Book;

Book Book_new();
void Book_init(Book *obj);

#endif
#ifndef Product_H
#define Product_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AbstractProduct.h"

/***********************/

typedef struct Product{

    AbstractProduct;
    double price;

    void (*set_price)();
    double (*get_price)();  
    // void (*display)();   

} Product;

Product Product_new();
void Product_init(Product *obj);

#endif
#ifndef TravelGuide_H
#define TravelGuide_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Book.h"

/***********************/

typedef struct TravelGuide{

    Book;
    char country[1000];
    void (*f)();

    void (*set_country)();
    char *(*get_country)();
    // void *(*display)();

} TravelGuide;

TravelGuide TravelGuide_new();
void TravelGuide_init(TravelGuide *obj);

#endif
产品.h

#ifndef AbstractProduct_H
#define AbstractProduct_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/***********************/

typedef struct AbstractProduct{

    int id;
    char name[1000];
    char description[1000];

    void (*set_id)();
    void (*set_name)();
    void (*set_description)();  
    int (*get_id)();    
    char *(*get_name)();    
    char *(*get_description)(); 
    void (*display)();  

} AbstractProduct;

AbstractProduct AbstractProduct_new();
void AbstractProduct_init(AbstractProduct *obj);

#endif
#ifndef Book_H
#define Book_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Product.h"

/***********************/

typedef struct Book{

    Product;
    char isbn[1000];
    char author[1000];
    char title[1000];

    void (*set_isbn)();
    void (*set_author)();
    void (*set_title)();    

    char *(*get_isbn)();
    char *(*get_author)();
    char *(*get_title)();   
    // void (*display)();   


} Book;

Book Book_new();
void Book_init(Book *obj);

#endif
#ifndef Product_H
#define Product_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AbstractProduct.h"

/***********************/

typedef struct Product{

    AbstractProduct;
    double price;

    void (*set_price)();
    double (*get_price)();  
    // void (*display)();   

} Product;

Product Product_new();
void Product_init(Product *obj);

#endif
#ifndef TravelGuide_H
#define TravelGuide_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Book.h"

/***********************/

typedef struct TravelGuide{

    Book;
    char country[1000];
    void (*f)();

    void (*set_country)();
    char *(*get_country)();
    // void *(*display)();

} TravelGuide;

TravelGuide TravelGuide_new();
void TravelGuide_init(TravelGuide *obj);

#endif
TravelGuide.h

#ifndef AbstractProduct_H
#define AbstractProduct_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/***********************/

typedef struct AbstractProduct{

    int id;
    char name[1000];
    char description[1000];

    void (*set_id)();
    void (*set_name)();
    void (*set_description)();  
    int (*get_id)();    
    char *(*get_name)();    
    char *(*get_description)(); 
    void (*display)();  

} AbstractProduct;

AbstractProduct AbstractProduct_new();
void AbstractProduct_init(AbstractProduct *obj);

#endif
#ifndef Book_H
#define Book_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Product.h"

/***********************/

typedef struct Book{

    Product;
    char isbn[1000];
    char author[1000];
    char title[1000];

    void (*set_isbn)();
    void (*set_author)();
    void (*set_title)();    

    char *(*get_isbn)();
    char *(*get_author)();
    char *(*get_title)();   
    // void (*display)();   


} Book;

Book Book_new();
void Book_init(Book *obj);

#endif
#ifndef Product_H
#define Product_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AbstractProduct.h"

/***********************/

typedef struct Product{

    AbstractProduct;
    double price;

    void (*set_price)();
    double (*get_price)();  
    // void (*display)();   

} Product;

Product Product_new();
void Product_init(Product *obj);

#endif
#ifndef TravelGuide_H
#define TravelGuide_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Book.h"

/***********************/

typedef struct TravelGuide{

    Book;
    char country[1000];
    void (*f)();

    void (*set_country)();
    char *(*get_country)();
    // void *(*display)();

} TravelGuide;

TravelGuide TravelGuide_new();
void TravelGuide_init(TravelGuide *obj);

#endif


在C中没有继承的东西。除非你实现它。据我所知,C++中也可以有一个结构/类成员。C表示在结构的第一个成员之前没有出现填充。所以你实际上可以(并且被允许)将文字角色*转换为人物*,并将其视为一个人+1@JohannesSchaub-litb您的评论比答案本身更能说明问题:)请注意,您必须只传递这些类型作为引用。你不能将它们复制到Person对象中,否则它会拼接。不支持但也不会妨碍。现实是什么?C++只是一个非常简单的调度库,在需要时调用很多编译器语法。最初的C++编译器最终生成了C代码。(实际上非常可读的C)嗯,假设C++编译器对你的平台可用!如果C编译器可用,那么C++编译器也是如此——只使用一个生成C作为输出的编译器。你救了我的命。我通常用Java编写代码,当遇到类似于您发布的代码时,我认为这是一个组合,当他们使用它时,我感到非常困惑。您可以在复杂的实际项目(如git)中看到它的用途。看见“继承”我以前也做过同样的事情。问题是,如果您实现“方法”的间接寻址,您将获得非常差的可读性,如
personDAO->getPersonById(personDAO,personDTO->getId(personDTO))。不幸的是,我看不到另一种方式。这不是一种组合吗?不,这是正确的继承。假设您有一个名为B的struct B类型的结构,B.member1将按照预期编译和工作。组合将类似于b.base.member1。GCC为您执行此魔术。实际上,在这个例子中,结构B的定义是两个整数。这只能在C中,而不是C++中?如果没有,请访问。C是语法。C++中的语法是非法的。虽然C++和类一样继承了结构,但是现在我感觉好多了!后缀
\u t
保留在POSIX中。做任何你想做的事,只是被告知,如果你为POSIX系统(例如Linux)编写代码,或者有人最终想要将你的代码移植到POSIX系统,你可能会遇到冲突。这在标准C(甚至不是C11)中实际上不起作用。我从未想过这一点。如果你让工会匿名,那就相当整洁了。然而,缺点是,为了避免嵌套变量,您需要列出所有父级。这是一种有趣的方法。但是,只要您键入
leopard.base
,继承/多态性的整个要点就被消除了。您不会遇到菱形继承问题吗<代码>豹子。基地。猫科动物。基地。动物。体重
和<代码>豹子。基地。动物。体重
?@Alexander Torstling不,你不会的
leopard.base.felidae.base.animal.weight
只是豹子.base.animal.weight的另一个名字,它在记忆中的同一个地方是同一个东西。看起来很棒。谢谢,很好的证据