2017-07-21 57 views
2

我想以两种方式打印我创建的对象的信息。在C中调用“方法”OOP

OOP无关的第一种方法是调用print函数。第二种方法类似于Python中的方法。我用joe->print();,它说error: too few arguments to function ‘joe->print’。如何处理它?

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

struct PERSON{ 
    char *name; 
    int age; 
    int height; 
    int weight; 
    void (*print)(struct PERSON *self); 
    void (*destroy)(struct PERSON *self); 

} ; 


typedef struct PERSON person; 

void person_print(person* who) 
{ 
    printf("Name: %s\n", who->name); 
    printf("Age: %d\n", who->age); 
    printf("Height: %d\n", who->height); 
    printf("Weight: %d\n", who->weight); 
} 

person *person_create(char *name, int age, int height, int weight) 
{ 
    person *who = malloc(sizeof(person)); 
    assert(who != NULL); 
    who->name = strdup(name); 
    who->age = age; 
    who->height = height; 
    who->weight=weight; 
    who->print=&person_print; 
    return who; 
    } 

void person_destroy(person *who) 
{ 
    assert(who != NULL); 

    free(who->name); 
    free(who); 
    } 

int main(int argc, char *argv[]) 
{ 
    person *joe = person_create("Joe Alex", 32, 64, 140); 
    person_print(joe); 
    //joe->print(); 

} 

还有一个问题让我感到困惑,当我们破坏使用功能void person_destroy,如何理解语句free(who->name) and free(who),为什么添加free(who->age)会导致错误推广的对象。如果我释放存储结构属性的空间,是否需要free(who)

+2

随着C,你必须显式*传递你的“object”*作为方法的第一个参数,OOP没有自动操作。当你想实现* virtual *方法时,你只需要将它作为函数指针的成员。对于一般的方法,你只需使用正常的功能(通常命名为' _ ()') –

+3

'joe-> print();'。声明是'void(* print)(struct PERSON * self);'。类型是'void(*)(struct PERSON *)'。它期望一个指向'struct PERSON'的指针。你通过它的地方?将该调用更改为'joe-> print(joe);'。 –

+1

顺便说一句,如果你想考虑的话,直接调用'print'函数仍然是OOP。它只是一个非虚拟方法的等价物,而'joe-> print'相当于一个虚拟方法。如果你有很多这样的方法,你可能想要创建一个const函数表,并在你的对象中只有一个指向它的指针。这也确保你不能混淆他们。 – spectras

回答

2

1部分:

你在使用print没有必要的参数错误的意见进行了说明。

你必须知道,有在C.没有出现神奇隐形this指针没有OO的东西...

如果你想使用这样的东西,你通过了!故事结局。 ;)

2部分:

我建议你抢初学者公司的C书,并检查有关动态内存使用情况的章节。

还有一个问题让我感到困惑,当我们使用functionvoid person_destroy销毁对象 ,如何理解语句 自由(如 - >名)和free(谁),为什么

非常简单的规则: 已分配的每块内存必须再次释放。

person *who = malloc(sizeof(person)); // Memory block #1 
... 
who->name = strdup(name);    // Memory block #2 

secod为字符串的副本分配内存并将地址分配给who->name

添加免费(who-> age)会导致错误提升。

由于who->age不是指针,但一个整数,当您使用它作为参数调用free当然,你会得到一个错误。 错误消息可能会告诉您有关该类型的不匹配。

如果我释放空间存储 这个结构的属性,会自由(谁)仍然有必要?

当然。 free应该如何知道它传递的内存块的入口? 在C中没有自动调用的析构函数