返回介绍

2.1 构造器和析构器

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

让我们来实现一个简单的字符串数据类型,这个数据类型将在接下来的集合中用到。对于新的字符串,我们分配一个动态缓存来保存字文本。当这个字符串被删除时,我们将回收其所占用的内存缓冲。

new() 负责创建一个对象, delete() 必须回收这个对象所占用的资源。 new() 预先知道它所创建的资源的类型,因为它的第一个参数将传递对这个对象的描述。基于这个参数,我们可以使用一系列的判断语句 if 来处理单个不同的要创建的对象。这样做的缺点是 new() 得完全包含对每个支持的对象要处理的代码。

现在 new() 拥有一个更大的问题。它负责创建对象并且返回对象的指针,这个指针被传递到 delete() ,也就是说, new() 必须在每个对象中安装特定的析构器信息。最明显的应用是使用一个指针,指向特定的析构器,这个析构器是类型描述符的一部分,被传进 new() 。到目前为止,我们需要像如下的声明:

struct type{
  size_t size;      /*size of an object*/
  void (*dtor)(void*);  /*destructor*/
};
struct String{
  char *text;       /*dynamic string*/
  const void* destroy;  /*locate destructor*/
};
struct Set{
  ...information...
  const void * destroy; /*locate destructor*/
};

似乎我们又有另外一个问题:在新的对象中,有人需要把析构器指针 dtor 从类型描述中拷贝到 destroy 中。而且这样的拷贝在不同的对象的类中会放到不同的位置。

初始化工作是 new() 的一部分,不同的类型会要求 new() 干不同的工作 - new() 可能需要不同的参数来处理不同的类型:

new(Set);       /*make a set*/
new(String,"text"); /*make a string*/

对于初始化我们使用另外一个指定类型的功能函数,这个函数我们称它为构造器。因为构造器和析构器都是类型指定的,不需要改变,我们把他们当成类型描述的一部分传递给 new() 函数。

注意,对于一个对象自身来说构造器和析构器并不是用来担当获取和释放内存的责任 - 这是 new()delete() 的工作。构造器被 new() 调用仅仅用来初始化 new() 所分配的内存。对于一个字符串,这需要涉及需要另外一块内存存储文本,但是对于 struct String 自身的内存却是使用 new() 来分配的。这个空间接下来会被 delete( ) 所释放。然而 delete() 首先 会调用析构器,析构器是对构造器所做的初始化进行反向操作。这步完成后才调用 delete() 释放 new() 所分配的内存。

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

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

发布评论

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