2.2 方法,消息,类和对象
delete()
必须能够在不知道对象类型的情况下定位析构器。因此修正了 2.1 部分的声明,我们必须坚持指针被用来定位析构器,这个指针必须放到所有对象的开始处传进 delete()
中,而不管他们的类型是什么。
这个指针应该指向什么呢 ?如果所有我们所拥有的是一个对象的地址,那么对于一个对象来说,指针给了我们访问指定类型的对象信息,就像对象的析构函数一样。似乎很可能我们将要创造一个类型指定的功能如一个函数用来显示对象,或者一个对象的比较函数 differ()
,或一个函数 clone()
去创建一个对象的完全拷贝。因此我们将使用一个指针指向函数指针表。
仔细看,我们会意识到这个表必须是类型描述的一部分,被传进 new()
, 显然的解决问题的答案就是让对象指向一个类型的完全描述:
struct Class {
size_t size;
void * (* ctor) (void * self, va_list * app);
void * (* dtor) (void * self);
void * (* clone) (const void * self);
int (* differ) (const void * self, const void * b);
};
struct String {
const void * class; /* must be first */
char * text;
};
struct Set{
const void* class /*must be first*/
...
};
每个对象将以一个指针开始,这个指针向对象的类型描述表,通过这个类型描述表,我们就可以定位一个对象的类型指定信息: .size
是 new()
所分配的对象所占用内存的大小; .dtor
指向被 delete()
( delete
用来销毁对象) 所调用的析构器;而 .differ
指向一个函数,这个函数用于比较对象。
继续往下看,我们会注意到,每个功能都是以对象而存在的,通过对象来选择这些功能。只有构造函数要处理部分初始化内存区域工作。我们都叫这些功能为一个对象的方法。调用一个对象的方法就是处理一则消息,我们使用参数 self
来标记消息接收的对象。因为我们使用基本的C函数功能, self
是不需要作为第一个参数而传进的。
多个对象共享相同的类型描述符,也就是说,他们需要相同数量大小的内存空间,可用于相同的方法。我们称所有拥有相同的类型描述符的对象为一类;单独的对象被称为类的实例。到目前为止,一个类,一个抽象数据类型,可能的值与操作结合的集合,即,一个数据类型,这些是极其相似的。
一个对象是一个类的实例,也就是说,它拥有一个描述,这个描述被 new()
所分配的内存所指示,并且这个描述被类的方法操作。普遍来说,一个对象是特殊数据类型的值。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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