返回介绍

3.6 动态连接

发布于 2025-02-24 22:44:37 字数 1633 浏览 0 评论 0 收藏 0

识别器是完善的。 value.h 对于算术表达式完全隐藏了求值程序,且与此同时指定了我们必须所实现的。 new() 携带描述符,如 Add 和合适的参数如指针对加的操作且返回一个表示和的指针。

struct Type {
     void * (* new) (va_list ap);
     double (* exec) (const void * tree);
     void (* delete) (void * tree);
};

void * new (const void * type, ...)
{  
va_list ap;
     void * result;

     assert(type && ((struct Type *) type) -> new);

     va_start(ap, type);
     result = ((struct Type *) type) -> new(ap);
     * (const struct Type **) result = type;
     va_end(ap);
     return result;
}

我们使用动态连接并传递一个对指定节点例程的调用,在例程中的 Add 分支处,必须常见一个节点,并且传进两个指针。

truct Bin {
     const void * type;
     void * left, * right;
};   

static void * mkBin (va_list ap)
{  
struct Bin * node = malloc(sizeof(struct Bin));

     assert(node);
     node -> left = va_arg(ap, void *);
     node -> right = va_arg(ap, void *);
     return node;
}

注意,只有 mkBin() 知道它创建的是什么。所有我们要求的是各个节点对于动态连接是以一个指针开始。这个指针被 new() 传进一遍于 delete() 能够调用到它指定节点的函数:

void delete (void * tree)
{
   assert(tree && * (struct Type **) tree
       && (* (struct Type **) tree) -> delete);

   (* (struct Type **) tree) -> delete(tree);
}

动态连接很优雅的避免了复杂难解的节点。 .new() 精确的创建了每个类型描述符的右节点:二元操作符拥有两个子孙。一元操作符拥有一个子孙,且值节点仅仅包含了值。 delete() 是一个非常简单的函数因为每个节点处理它自己的销毁过程:二元操作符删除两个子树并且释放他们自己的节点,一元操作符仅仅删除一个子树,且值节点仅仅释放自己。变量和常量甚至可以留到后面 - 对于 delete() 的回应他们简单的什么也不做。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文