2.5 实现 - String
我们通过写这些方法实现字符串,这些方法需要被放入类型描述 String
中。对于实现一个新的数据类型,动态连接使我们清晰的确定出那些功能函数需要实现。
构造器从新获得文本,传递给 new()
,并把这些动态拷贝存储进通过 new()
创建的 struct String
中。
struct String {
const void * class; /* must be first */
char * text;
};
static void * String_ctor (void * _self, va_list * app)
{ struct String * self = _self;
const char * text = va_arg(* app, const char *);
self -> text = malloc(strlen(text) + 1);
assert(self -> text);
strcpy(self -> text, text);
return self;
}
在构造器中,我们紧紧需要初始化 .text 因为 new() 已经建立了 .class 。
析构器释放被字符串控制的动态内存。由于 delete() 只在 self 为非空的情况下调用 析构器,所以我们不需要做其他参数检查,代码如下:
static void * String_dtor (void * _self)
{ struct String * self = _self;
free(self -> text), self -> text = 0;
return self;
}
String_clone()
是对字符串的一个拷贝。接下来,源和源的拷贝都将被传进 delete()
中,因此我们必须对字符串的文本做一个动态内存的拷贝。这个工作通过调用 new()
很容易实现。
static void * String_clone (const void * _self)
{ const struct String * self = _self;
return new(String, self -> text);
}
毫无疑问,对于 String_differ
如果我们比较同一个字符串对象,则返回假,若果我们比较两个不同的字符串对象,返回真,如果我们想比较字符串文本的差异可试着使用 strcmp()
:
static int String_differ (const void * _self, const void * _b)
{ const struct String * self = _self;
const struct String * b = _b;
if (self == b)
return 0;
if (! b || b -> class != String)
return 1;
return strcmp(self -> text, b -> text);
}
类型描述符是独一无二的 - 这里我们要确定一个因素,即:我们的第二个参数是否为字符串文本。
所有这些方法都应该使用关键字 static
来修饰。因为这些方法只能通过 new()
和 delete()
,或者选择器调用。对于通过类型描述符的方式指定的选择器都是可用的方法。
#include “new.r”
static const struct Class _String = {
sizeof(struct String),
String_ctor, String_dtor,
String_clone, String_differ
};
const void * String = & _String;
在 String.h 中声明 String.c 中包含的公有方法,new.h 中声明 new.c 中包含的公有方法。以便于正确的初始化类型描述符,这里也包含了一个私有的头文件 new.r ,此文件中包含了 2.2 部分定义的 struct Class 类型描述。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论