【问题标题】:Hook on object in std::list. Pointer or iterator?挂钩 std::list 中的对象。指针还是迭代器?
【发布时间】:2013-07-14 08:02:51
【问题描述】:

我寻找了相同类型的问题,但我没有找到我的问题的答案(存在问题): 我应该选择什么类型的钩子来控制列表中的对象? 我在指针和迭代器之间摇摆不定。

容器在开始时已被填充,之后不应调整大小。钩子是我用来根据用户一时兴起在我的对象之间切换并在我的算法中只操作一个变量的方式。

在所有情况下,我都必须通过一个迭代器来找到要挂钩的正确对象。但是哪一个是最佳实践/使用?

// 10 object list
std::list <Object> List(10);

std::list <Object>::iterator it = List.begin();
Object *pt = NULL;

// Select the 3rd object
advance(it, 3);
pt = &(*it);

// Access to object member...
it->member;
pt->member;

与迭代器相反,指针不允许访问邻居,但可能不安全。 最好的做法是什么?

【问题讨论】:

  • 与大多数标准容器不同,在std::list 中,除非删除相应的元素,否则迭代器永远不会失效,因此它与原始指针一样(不)安全,但具有额外的好处,正如您所说, 以便能够从当前项目开始迭代。由于迭代器是非常轻量级的对象,因此选择其中任何一个都不会对性能产生任何影响,因此这完全取决于您。
  • 如果容器在填充后没有更改,并且考虑到您示例中的访问模式,您可能会考虑使用您访问的std::vector 变为vec[3],这将为您提供对象。

标签: c++ list pointers iterator


【解决方案1】:

这取决于你想用“钩子”做什么。如果你使用 一个迭代器,它可以作为移动的起点 在列表中向前或向后。如果你使用指针,你可以 也指向列表之外的对象。最后,它 取决于您希望代码如何发展。

【讨论】:

  • 钩子的目标是提供一个接口对象列表和我的算法的常量对象。它允许用户随心所欲地在容器中的不同对象之间切换(在我的情况下,对象代表工作台的配置)。
【解决方案2】:

将指针或迭代器存储到容器中是非常危险的,因为您可能会在使用它们时发现它们是无效的(即,如果容器或数据发生变化)。

更通用和更强大的方法可能是使用地图而不是列表。每个值都由一个键(您喜欢的任何类型)标识,您可以轻松地存储这些键并在使用它们之前检查它们是否有效,例如:

std::map<int, std::string> data;

// Add stuff to the map
data[5] = "blah";
data[27] = "foo";

// Check if a key exists
if (data.find(31) == data.end()) {
    // Key 31 does NOT exist
} else {
    // Key 31 DOES exist
}

需要注意的一点是地图是按键值排序的。这意味着如果元素的顺序很重要,那么您需要仔细选择键。

【讨论】:

  • 我不熟悉 map 和 set 但这似乎是 hook 功能的一个很好的替代品。我会研究这个方式,谢谢!
【解决方案3】:

在大多数情况下使用引用:

Object& ref = *it;
ref.member

它的行为就像一个指针(所以可以随意将它传递给函数),但你不能对它进行指针运算(ref++ 实际上会在 Object 上调用 operator++())。也不能从 null 初始化(当你尝试创建引用时会报错)。

要记住的一件事是,您仍然需要将对象分配到某个地方。如果说某个函数从 List 中删除了 Object,那么您不应该再使用 ref

【讨论】:

  • 引用在我的情况下没有用,因为钩子是在程序开始时声明的,即使列表为空,也要设置“NULL”或“List.begin()”,然后进行关联分配由用户选择。
猜你喜欢
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
相关资源
最近更新 更多