Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的继承_C_Inheritance - Fatal编程技术网

C语言中的继承

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

我正在玩用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_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我本来想出去喝点啤酒,但现在我回来了,这是一个愚蠢的错误,关于选角的可能性,好主意,我已经修正了我的答案。