理解OOPC,我做得对吗?

理解OOPC,我做得对吗?,c,oop,C,Oop,我读了Alex的书《使用ANSIC进行面向对象编程》 到目前为止,我们试图对一个非常基本的字符串类进行建模- 代码如下: main.c #include <stdio.h> #include <stdlib.h> #include "class.h" #include "mystring.h" extern const void *String_c; int main() { String *my = new(String_c, "A random s

我读了Alex的书《使用ANSIC进行面向对象编程》

到目前为止,我们试图对一个非常基本的字符串类进行建模-

代码如下:

main.c

#include <stdio.h>
#include <stdlib.h>
#include "class.h"
#include "mystring.h"

extern const void *String_c;

int main() {
        String *my = new(String_c, "A random string");
        char *text = my->str(my);
        printf("String contains %s of length %d", text, my->length(my));
        delete(my);
        free(text);
        return 0;
}
/*
 * class.c
 *
 *  Created on: 22-Mar-2014
 *      Author: nilesh
 */

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

#include "class.h"

void *new(const void *_class, ...) {
        printf("\nCreating new\n");
        const Class *class = _class;
        void *p = calloc(1, class->size);
        assert(p);
        * (const Class **) p = class;
        if(class->ctor) {
                va_list ap;
                va_start(ap, _class);
                p = class->ctor(p, &ap);
                va_end(ap);
        }
        return p;
}

void delete(void *object) {
        printf("\nDelete\n");
        const Class **class = object;
        if(object && *class && (*class)->dtor)
                (*class)->dtor(object);
        free(object);
        object = NULL;
}
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "mystring.h"

struct _string {
        char *data;
        int length;
};

static int length(String *self) {
        return self->_->length;
}

static char* str(String *self) {
        char *ret = malloc(sizeof(char) * self->_->length);
        memcpy(ret, self->_->data, sizeof(char)*self->_->length);
        return ret;
}

void* ctor(void *_self, va_list *app) {
        printf("\nConstructor called\n");
        String *self = _self;
        self->_ = malloc(sizeof(struct _string));
        char *text = va_arg(*app, char *);
        self->_->length = strlen(text);
        self->_->data  = malloc(sizeof(char) * self->_->length);
        memcpy(self->_->data, text, sizeof(char) * self->_->length);

        self->length = length;
        self->str = str;

        return self;
}

void dtor(void *_self) {
        printf("\nDestructor called\n");
        String *self = _self;
        free(self->_);
        free(self->_->data);
        self->_->data = NULL;
}

Class _string_class = {sizeof(String), ctor, dtor};
const void *String_c = &_string_class;
在删除中不起作用,而

Class **class = object
工作


从某种意义上讲,前者不调用
dtor
,而是调用length,后者则调用
(*class)->dtor
,这是可行的。

简单的回答是
class
属于
类**
<只有当
class
属于
class*
类型时,code>class->dtor才会起作用

您可能会因为双重间接性而感到困惑,因此这里有一个较长的解释:

考虑一下结构布局。假设您有这样一个简单的结构:

struct example {
    int xpto;
    char a[10];
}
如果调用函数
f()
并将指针
p
传递给
struct example
,那么
f()
可以自由地将这样的指针投射到
int*
。取消引用这样的指针会产生与
p->xpto
相同的结果。也就是说,
p->xpto
*(int*)p
是等价的。发生这种情况的原因是,结构组件以不断增加的内存地址进行布局
xpto
是第一个成员,意味着它位于偏移量0处。换句话说,对于指向结构示例的任何指针,由
p
指向的地址处的第一个
sizeof(int)
字节属于
xpto

您的字符串结构定义为:

struct string {
        const Class *class;
        struct _string *_;
        int (*length) (String *self);
        char* (*str) (String *self);
};
这表明在
struct string
的偏移量0处有一个指向
Class
的(只读)指针。当您在
main()
中调用
delete(my)
时,您给它一个指向
struct string
的指针-因此,
my
指向的地址中的第一个
sizeof(const Class*)
字节是指向
类的指针。就像我们在
struct-example
的示例中所做的那样,我们将
p
转换为指向第一个成员的指针-将这样的指针转换为
Class**
(第一个成员是
Class*
,因此指向第一个成员的指针是
Class**
)可以直接访问第一个字段(并且只有第一个字段)

因此,
delete()
将您给它的指针强制转换为
类**
,因为这样做,取消对此类指针的引用将生成一个
类*


为什么
class->dtor()
不起作用?因为
class
属于
class**
类型,所以,
class>dtor
,相当于
(*class)。dtor
无效:
*class
属于
class*
类型,它不是一个结构,因此,没有名为
dtor
的成员。您必须使用
(*类)->dtor
,因为这与
(*(*类))相同。dtor

简单的回答是
属于
类**
<只有当
class
属于
class*
类型时,code>class->dtor
才会起作用

您可能会因为双重间接性而感到困惑,因此这里有一个较长的解释:

考虑一下结构布局。假设您有这样一个简单的结构:

struct example {
    int xpto;
    char a[10];
}
如果调用函数
f()
并将指针
p
传递给
struct example
,那么
f()
可以自由地将这样的指针投射到
int*
。取消引用这样的指针会产生与
p->xpto
相同的结果。也就是说,
p->xpto
*(int*)p
是等价的。发生这种情况的原因是,结构组件以不断增加的内存地址进行布局
xpto
是第一个成员,意味着它位于偏移量0处。换句话说,对于指向结构示例的任何指针,由
p
指向的地址处的第一个
sizeof(int)
字节属于
xpto

您的字符串结构定义为:

struct string {
        const Class *class;
        struct _string *_;
        int (*length) (String *self);
        char* (*str) (String *self);
};
这表明在
struct string
的偏移量0处有一个指向
Class
的(只读)指针。当您在
main()
中调用
delete(my)
时,您给它一个指向
struct string
的指针-因此,
my
指向的地址中的第一个
sizeof(const Class*)
字节是指向
类的指针。就像我们在
struct-example
的示例中所做的那样,我们将
p
转换为指向第一个成员的指针-将这样的指针转换为
Class**
(第一个成员是
Class*
,因此指向第一个成员的指针是
Class**
)可以直接访问第一个字段(并且只有第一个字段)

因此,
delete()
将您给它的指针强制转换为
类**
,因为这样做,取消对此类指针的引用将生成一个
类*


为什么
class->dtor()
不起作用?因为
class
属于
class**
类型,所以,
class>dtor
,相当于
(*class)。dtor
无效:
*class
属于
class*
类型,它不是一个结构,因此,没有名为
dtor
的成员。您必须使用
(*类)->dtor
,因为这与
(*(*类))相同。dtor

简单的回答是
属于
类**
<只有当
class
属于
class*
类型时,code>class->dtor
才会起作用

您可能会因为双重间接性而感到困惑,因此这里有一个较长的解释:

考虑一下结构布局。假设您有这样一个简单的结构:

struct example {
    int xpto;
    char a[10];
}
如果调用函数
f()
并将指针
p
传递给
struct example
,那么
f()
可以自由地将这样的指针投射到
int*
。取消引用这样的指针会产生与
p->xpto
相同的结果。也就是说,
p->xpto