我找了相同类型的问题,但我找不到问题的答案(存在的问题): 我应该选择什么类型的钩子来控制列表中的对象? 我在指针和迭代器之间摇摆不定。
容器在开头填充,之后不应调整大小。钩子是我用来在用户心血来潮之间切换对象并在我的算法中只操纵一个变量的方式。
在所有情况下,我必须通过迭代器来找到要挂钩的正确对象。但哪一个是最佳实践/使用?
// 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;
与迭代器相反,指针允许不访问邻居,但可能不安全。 什么是最好的实践?
答案 0 :(得分:2)
这取决于你想用“钩子”做什么。如果你使用 一个迭代器,它可以用作移动的起点 在列表中向前或向后。如果你使用指针,你可以 也指向列表之外的对象。最后,它 取决于您对代码的发展方式。
答案 1 :(得分:1)
将指针或迭代器存储到容器中是非常危险的,因为您可能会发现它们在您使用它们时是无效的(即,如果容器或数据发生更改)。
更通用和更健壮的方法可能是使用地图而不是列表。每个值都由一个键(您喜欢的任何类型)标识,您可以轻松地存储键并在使用它们之前检查它们是否有效,例如:
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
}
但要注意的一件事是地图按键值排序。这意味着如果元素序列很重要,那么您需要仔细选择密钥。
答案 2 :(得分:0)
在大多数情况下使用引用:
Object& ref = *it;
ref.member
它的行为类似于指针(因此可以随意传递函数)但是你不能在它上面做指针算术(ref++
实际上会调用Object上的operator++()
。此外,您无法从null初始化它(当您尝试创建引用时将报告为错误。)
有一点需要记住,你仍然需要将对象放在某个地方。如果说某个函数从列表中删除了对象,则不应再使用ref
。