理解OOPC,我做得对吗?
我读了Alex的书《使用ANSIC进行面向对象编程》 到目前为止,我们试图对一个非常基本的字符串类进行建模- 代码如下: main.c理解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
#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