C语言中的继承
我正在玩用C实现继承的游戏。我编写了它的以下两个变体。方法1在运行程序时崩溃,但方法2工作正常。我在方法1中做错了什么 方法1:C语言中的继承,c,inheritance,C,Inheritance,我正在玩用C实现继承的游戏。我编写了它的以下两个变体。方法1在运行程序时崩溃,但方法2工作正常。我在方法1中做错了什么 方法1: #包括 #包括 typedef结构基类 { INTA; }基础; typedef结构派生的_类 { int b; 基地*基地ptr; }衍生的; 内部主(空){ 导出*der_ptr; deru ptr=(派生*)malloc(sizeof(派生)); der_ptr->b=5; 订单->基本订单->a=10; printf(“%d%d”,der_ptr->b,der
#包括
#包括
typedef结构基类
{
INTA;
}基础;
typedef结构派生的_类
{
int b;
基地*基地ptr;
}衍生的;
内部主(空){
导出*der_ptr;
deru ptr=(派生*)malloc(sizeof(派生));
der_ptr->b=5;
订单->基本订单->a=10;
printf(“%d%d”,der_ptr->b,der_ptr->base_ptr->a);
}
方法2:
#包括
#包括
typedef结构基类
{
INTA;
}基础;
typedef结构派生的_类
{
int b;
基础ptr;
}衍生的;
内部主(空){
导出*der_ptr;
deru ptr=(派生*)malloc(sizeof(派生));
der_ptr->b=5;
订单->基本订单a=10;
printf(“%d%d”,der_ptr->b,der_ptr->base_ptr.a);
}
方法2中没有错误,但这取决于您试图实现的目标
但是,在方法1中,您从不为指针Base*Base_ptr
分配空间,然后取消对它的引用,这就是程序崩溃的原因
<>这一点,注意我已经移除了Casic,因为它在C++中是需要的,在c中不需要它。
der_ptr = malloc(sizeof(Derived));
正在为一个int
和一个指针分配空间,因此sizeof(派生)=sizeof(int)+sizeof(void*)
,如果要访问base_ptr
的a
成员,在分配der_ptr
并检查分配是否成功后,需要为其分配空间,然后分配给它的base_ptr
成员,如下所示
der_ptr->base_ptr = malloc(sizeof(Base));
#include<stdio.h>
#include<stdlib.h>
typedef struct base_class
{
int a;
} Base;
/*
typedef struct derived_class
{
int b;
Base *base_ptr;
} Derived;
*/
/* the order matters, this way you can cast Derived to Base */
typedef struct derived_class
{
Base *base_ptr;
int b;
} Derived;
int main(void) {
Derived *der_ptr;
der_ptr = malloc(sizeof(Derived));
if (der_ptr == NULL)
return 1;
der_ptr->b = 5;
der_ptr->base_ptr = malloc(sizeof(Base));
if (der_ptr->base_ptr == NULL)
{
free(der_ptr);
return 2;
}
der_ptr->base_ptr->a = 10;
printf("%d %d", der_ptr->b, der_ptr->base_ptr->a);
free(der_ptr->base_ptr);
free(der_ptr);
}
然后您可以访问base\u ptr
的a
成员
<>也请注意,与C++中的<代码>新< /COD>运算符不同,当它失败时,它会做一些异常处理的事情,在C中你应该检查<代码> MALLC/<代码>返回一个有效的指针,在失败时它返回代码> null < /C> >
所以,方法1应该是这样工作的
der_ptr->base_ptr = malloc(sizeof(Base));
#include<stdio.h>
#include<stdlib.h>
typedef struct base_class
{
int a;
} Base;
/*
typedef struct derived_class
{
int b;
Base *base_ptr;
} Derived;
*/
/* the order matters, this way you can cast Derived to Base */
typedef struct derived_class
{
Base *base_ptr;
int b;
} Derived;
int main(void) {
Derived *der_ptr;
der_ptr = malloc(sizeof(Derived));
if (der_ptr == NULL)
return 1;
der_ptr->b = 5;
der_ptr->base_ptr = malloc(sizeof(Base));
if (der_ptr->base_ptr == NULL)
{
free(der_ptr);
return 2;
}
der_ptr->base_ptr->a = 10;
printf("%d %d", der_ptr->b, der_ptr->base_ptr->a);
free(der_ptr->base_ptr);
free(der_ptr);
}
#包括
#包括
typedef结构基类
{
INTA;
}基础;
/*
typedef结构派生的_类
{
int b;
基地*基地ptr;
}衍生的;
*/
/*顺序很重要,通过这种方式,您可以将派生类型转换为基本类型*/
typedef结构派生的_类
{
基地*基地ptr;
int b;
}衍生的;
内部主(空){
导出*der_ptr;
der_ptr=malloc(sizeof(派生));
if(der_ptr==NULL)
返回1;
der_ptr->b=5;
der_ptr->base_ptr=malloc(sizeof(base));
如果(订单->基本订单==NULL)
{
免费(DERUPTR);
返回2;
}
订单->基本订单->a=10;
printf(“%d%d”,der_ptr->b,der_ptr->base_ptr->a);
免费(订单->基本订单);
免费(DERUPTR);
}
请注意,现在成员按此顺序排列,您还可以将
派生*
强制转换为基*
。方法1因以下代码行而崩溃:
der_ptr->base_ptr->a=10;
问问自己:
der_ptr->base_ptr
的值是多少?因为其他人已经指出您没有为base分配存储,所以方法1会导致随机访问内存中的某些位置
如果您对在C中实现类似OO的接口和更高级别的编程感兴趣,那么我建议您仔细研究一下,您会惊讶于它所提供的表达能力。它的价值是什么,在方法2中交换
struct-derived_-class
的元素将允许您安全地将derived*
强制转换为Base*
。这不是重复的,但可能对您有用:您正在以错误的顺序释放内存。但我认为,修正这个问题并提及@Dashwuff在评论中所说的内容(将基数放在开头)将使你的答案几乎完美。@5gon12eder我本来想出去喝点啤酒,但现在我回来了,这是一个愚蠢的错误,关于选角的可能性,好主意,我已经修正了我的答案。