我应该返回一个迭代器还是指向 STL 容器中元素的指针?

发布于 2024-09-19 20:21:47 字数 732 浏览 2 评论 0原文

我正在开发一个用于将现有代码移植到不同平台的引擎。现有的代码是使用第三方API开发的,我的引擎将根据我的新平台重新定义那些第三方API函数。

以下定义来自 API:

typedef unsigned long shape_handle;    
shape_handle make_new_shape( int type );

我需要重新定义 make_new_shape,并且可以选择重新定义 shape_handle

我已经定义了这个结构(简化):

struct Shape
{
    int type
};

make_new_shape 的调用者不关心 Shape 的底层结构,它只需要一个它的“句柄”,以便它可以调用如下函数:

void `set_shape_color( myshape, RED );`

其中 myshape 是形状的句柄。

我的引擎将管理 Shape 对象的内存,并且其他要求指示引擎应将 Shape 对象存储在列表或其他可迭代容器中。

我的问题是,表示此句柄的最安全方法是什么 - 如果 Shape 本身将存储在 std::list 中 - 迭代器、指针、索引?

I am developing an engine for porting existing code to a different platform. The existing code has been developed using a third party API, and my engine will redefine those third party API functions in terms of my new platform.

The following definitions come from the API:

typedef unsigned long shape_handle;    
shape_handle make_new_shape( int type );

I need to redefine make_new_shape and I have the option to redefine shape_handle.

I have defined this structure ( simplified ):

struct Shape
{
    int type
};

The Caller of make_new_shape doesn't care about the underlying structure of Shape, it just needs a "handle" to it so that it can call functions like:

void `set_shape_color( myshape, RED );`

where myshape is the handle to the shape.

My engine will manage the memory for the Shape objects and other requirements dictate that the engine should be storing Shape objects in a list or other iterable container.

My question is, what is the safest way to represent this handle - if the Shape itself is going to be stored in a std::list - an iterator, a pointer, an index?

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冧九 2024-09-26 20:21:47

如果您在删除对象后尝试访问迭代器或指针,它们都会做坏事,因此本质上两者都不安全。迭代器的优点是它可以用来访问集合中的其他成员。

因此,如果您只想访问您的形状,那么指针将是最简单的。如果您想迭代列表,请使用迭代器。

索引在列表中毫无用处,因为 std::list 不会重载 [] 运算符。

Both an iterators or a pointers will do bad stuff if you try to access them after the object has been deleted so neither is intrinsically safer. The advantage of an iterator is that it can be used to access other members of your collection.

So, if you just want to access your Shape then a pointer will be simplest. If you want to iterate through your list then use an iterator.

An index is useless in a list since std::list does not overload the [] operator.

风和你 2024-09-26 20:21:47

答案取决于您的表示:

  • 对于 std::list,使用 iterator (而不是指针),因为 iterator 允许您删除元素而不遍历整个列表。
  • 对于 std::mapboost::unordered_map,请使用 Key (当然)

如果您使用关联,您的设计将会更加强大容器,因为关联容器使您能够查询对象是否存在,而不是调用未定义的行为。

尝试对 mapunordered_map 进行基准测试,看看哪一个在您的情况下更快:)

The answer depends on your representation:

  • for std::list, use an iterator (not a pointer), because an iterator allows you to remove the element without walking the whole list.
  • for std::map or boost::unordered_map, use the Key (of course)

Your design would be much strong if you used an associative container, because associative containers give you the ability to query for the presence of the object, rather than invoking Undefined Behavior.

Try benchmarking both map and unordered_map to see which one is faster in your case :)

素食主义者 2024-09-26 20:21:47

IIF 内部表示将是形状列表,则指针和迭代器是安全的。一旦分配了元素,就不会发生重定位。出于明显的访问性能原因,我不会推荐索引。如果是列表,则为 O(n)。

如果您使用向量,则不要使用迭代器或指针,因为当超出向量容量时可以重新定位元素,并且您的指针/迭代器将变得无效。

如果您想要一个无论内部容器如何都是安全的表示,那么创建一个指向形状的指针的容器(列表/向量),并将形状指针返回给您的客户端。即使容器在内存中移动,Shape 对象也将保留在同一位置。

IIF the internal representation will be a list of Shapes, then pointers and iterators are safe. Once an element is allocated, no relocation will ever occur. I wouldn't recommend an index for obvious access performance reasons. O(n) in case of lists.

If you were using a vector, then don't use iterators or pointers, because elements can be relocated when you exceed the vectors capacity, and your pointers/iterators would become invalid.

If you want a representation that is safe regardless of the internal container, then create a container (list/vector) of pointers to your shapes, and return the shape pointer to your client. Even if the container is moved around in memory, the Shape objects will stay in the same location.

2024-09-26 20:21:47

迭代器并不比指针更安全,但如果您使用的是经过检查的 STL 实现,那么迭代器的诊断能力要比原始指针好得多!

例如,在调试版本中,如果返回指向列表元素的指针,然后擦除该列表元素,则会出现悬空指针。如果您访问它,您会崩溃,并且您看到的只是垃圾数据。这可能会导致很难找出问题所在。

如果您使用迭代器并且有一个经过检查的 STL 实现,那么一旦您访问已擦除元素的迭代器,您就会收到类似“迭代器已失效”的消息。那是因为你删除了它指向的元素。 Boom,您刚刚为自己节省了大量的调试工作。

因此,不是 O(n) 性能的索引。在指针和迭代器之间 - 总是迭代器!

Iterators aren't safer than pointers, but they have much better diagnostics than raw pointers if you're using a checked STL implementation!

For example, in a debug build, if you return a pointer to a list element, then erase that list element, you have a dangling pointer. If you access it you get a crash and all you can see is junk data. That can make it difficult to work out what went wrong.

If you use an iterator and you have a checked STL implementation, as soon as you access the iterator to an erased element, you get a message something like "iterator was invalidated". That's because you erased the element it points to. Boom, you just saved yourself potentially a whole lot of debugging effort.

So, not indices for O(n) performance. Between pointers and iterators - always iterators!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文