【问题标题】:Avoid needing empty constructor for header node of collection避免集合的头节点需要空构造函数
【发布时间】:2013-12-30 19:07:08
【问题描述】:

我有一个正在编写的集合,它是一种链表形式,但它有一个标题节点。每个节点都存储一个模板类型 T 的对象。如果我不需要初始化头节点,那么我不需要要求 T 有一个空的构造函数。此外,我从来没有任何理由查看头节点中的对象。有没有办法让为该对象保留的内存未初始化?那我就不需要客户端实现一个空的构造函数了。

【问题讨论】:

  • 请显示一些代码,会有所帮助。
  • 有两种方法可以做到这一点。 1) 让班主任与孩子不同。 2)将值分配给堆(可空类型)。我更喜欢1。

标签: c++ constructor linked-list nodes default-constructor


【解决方案1】:

您可以在您的节点中使用union,并仅在使用时在其中构造值。使用这种方法是在单独分配内容和为头节点使用不同类型之间的中间:它仍然会为未使用的内容占用内存,但它既不需要额外的分配/间接,也不需要内容的默认构造函数。

【讨论】:

  • 我认为我最喜欢这个答案,但在这种情况下我无法弄清楚如何编写析构函数。不幸的是,头节点不知道它是头节点。有没有办法将参数传递给析构函数来告诉它是否调用 T 的析构函数?我可以显式调用 T 的析构函数吗?
  • @dspyz:没有任何方法可以将与正在破坏的对象不同的参数传递给析构函数。您需要能够根据对象的状态确定 union 中存储的对象类型。
【解决方案2】:

我假设您知道std::liststd::forward_list。如果是这样,并且您仍然想编写自己的链接列表来获得您想要的行为,最好的选择是使用std::aligned_storage 与放置new

或者,如果您有权使用 boost,您可以将该责任删除到 boot::optional

http://en.cppreference.com/w/cpp/types/aligned_storage

http://www.boost.org/doc/libs/1_55_0/libs/optional/doc/html/index.html

【讨论】:

  • 具体来说,我正在编写一个forward_list,其中元素可以被擦除而不是erase_after'd(因为迭代器在内部停留在它指向的位置后面一步),并且迭代器在其元素时不会失效被抹去。它们被有效地移动到下一个有效元素(每个节点都像 shared_ptr 一样保留一个 ptr_count,并且只有当该计数变为零时才会从内存中删除。当一个元素被擦除时,它的指针会指向前一个元素,因此任何迭代器坐在上面可以跟随链回到下一个有效元素)
  • @dspyz 只写一个代理迭代器和一些无帮助的函数不是更有意义吗?即erase(my_list, my_proxy_iter);??
  • 我遇到了严重的内存问题。在现有 STL 结构之上构建它将不可避免地需要额外的指针/内存。即,如果我只保留一个 shared_ptrs 的 forward_list,那么我需要额外的内存来存储指向计数的指针,而这样它就可以简单地成为节点对象的一部分
猜你喜欢
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多