C中的结构inheritance

我可以inheritanceC中的结构吗? 如果是的话,怎么样?

你可以得到最接近的习惯用法:

typedef struct { // base members } Base; typedef struct { Base base; // derived members } Derived; 

由于Derived开始于一个Base的副本,你可以这样做:

 Base *b = (Base *)d; 

其中dDerived一个实例。 所以他们是多态的。 但是使用虚拟方法是另一个挑战 – 要做到这一点,您需要在Base中包含一个vtable指针,包含指向接受Base作为第一个参数(您可以将其命名的函数)的函数指针。

通过这一点,你可以使用C ++!

与C ++不同,C没有明确的inheritance概念。 但是,您可以在另一个结构中重用结构:

 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中Typesafeinheritance的思想。

例如:

 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; 

如果你的编译器支持匿名结构,你可以这样做:

 typedef struct Base { // base members } Base_t; typedef struct { struct Base; //anonymous struct // derived members } Derived_t; 

这样,基本stuct成员可以直接进入,这是更好的。

如果你想使用一些海湾合作委员会的魔术(我会假设会与微软的C编译器),你可以做一些事情:

 struct A { int member1; }; struct B { struct A; int member2; } 

有了gcc,你可以使用-fms-extensions(允许像Microsofts编译器这样的无名结构成员)来编译。 这与Daniel Earwicker给出的解决scheme类似,只是它允许您访问结构B实例上的memeber1。 即B.member1而不是BAmember1。

这可能不是最可移植的方法,如果使用C ++编译器(不同的语言语义是指重新声明/定义结构A而不是实例化),将不起作用。

但是,如果你居住在海湾合作委员会/ C地区,只有它能够正常工作,并按照你的意愿去做。

anon(和其他人相似)的答案略有差异。 对于一级深度inheritance,可以执行以下操作:

 #define BASEFIELDS \ char name[NAMESIZE]; \ char sex typedef struct { BASEFIELDS; } Person; typedef struct { BASEFIELDS; char job[JOBSIZE]; } Employee; typedef struct { BASEFIELDS; Employee *subordinate; } Manager; 

这样,接受Person指针的函数将接受指向Employee或Manager的指针(与其他答案一样),但在这种情况下,初始化也是自然的:

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

VS

 # as in anon's answer Employee e = { .person.name = "..."; ... }; 

我相信这是一些stream行的项目如何做(如libuv)

更新:在使用结构和联合的libsdl事件实现中也有类似(但不一样)的概念。

你可以做上面提到的

 typedef struct { // base members } Base; typedef struct { Base base; // derived members } Derived; 

但是如果你想避免指针转换,你可以使用指针来指向BaseDerivedunion

这工作与-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); } 

AbstractProduct.c

 #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; } 

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 

Book.c

 #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; } 

Book.h

 #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 

Product.c

 #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; } 

Product.h

 #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 

TravelGuide.c

 #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; } 

TravelGuide.h

 #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 

Makefile文件

 .PHONY: clean define ANNOUNCE_BODY *********************************************** ************ start make ************** *********************************************** endef all: $(info $(ANNOUNCE_BODY)) clear; if [ -f binary/main ]; then rm binary/main; fi; # compiler gcc $(INC) -c -fms-extensions main.c -o binary/main.o gcc $(INC) -c -fms-extensions AbstractProduct.c -o binary/AbstractProduct.o gcc $(INC) -c -fms-extensions Product.c -o binary/Product.o gcc $(INC) -c -fms-extensions Book.c -o binary/Book.o gcc $(INC) -c -fms-extensions TravelGuide.c -o binary/TravelGuide.o # linker gcc binary/main.o \ binary/AbstractProduct.o \ binary/Product.o \ binary/Book.o \ binary/TravelGuide.o \ -o \ binary/main 

C不是一个面向对象的语言,因此没有inheritance。

你可以模拟它,但是你不能真正的inheritance。

不,你不能。 在C中,OOP的最佳方法是使用ADT 。

你不能。 C不支持inheritance的概念。