由于 STL 容器要求所有内容都是可复制和可分配的,那么在处理不可复制对象时,首选的习惯用法是什么?
我可以想到两种不同的方法:
存储(智能)指针而不是 STL 容器中的对象。
摆脱 STL 容器并实现我自己的列表(例如,每个对象必须包含指向下一个对象的指针)。
第二种方法的主要缺点是析构函数的实现(是否应该以递归方式在当前对象之前销毁“下一个”对象?)
由于 STL 容器要求所有内容都是可复制和可分配的,那么在处理不可复制对象时,首选的习惯用法是什么?
好吧,实际上对于 C++11,它们要求对象是可移动的。由于emplace_*
方法,只有某些操作需要它们是可分配的。
我可以想到两种不同的方法:
存储(智能)指针而不是 STL 容器中的对象。
摆脱 STL 容器并实现我自己的列表(例如,每个对象必须包含指向下一个对象的指针)。
这两种方法当然是可行的。
std::unique_ptr<YourObject>
在 C++11 中,带有元素的 STL 容器可能是最佳选择。从头到尾都是标准的。基于节点的容器可能存在轻微的性能问题,因为节点和它们指向的元素将是不同的内存区域;但它通常是难以察觉的。
如果它是可感知的,或者如果你不能使用 C++11,那么你应该学习侵入式容器,它包括用钩子增加你的对象,以便它们可以将自己排列到列表中。显然,有一个 Boost 库:Boost.Intrusive。
你说的不可移动?
老实说,我会挑战大多数认为不应移动对象的设计。移动的唯一问题与对象身份有关,以及使指向被移动对象的指针无效的潜在问题(因此在后面存在悬空指针)。这通常可以通过智能指针和/或工厂方法来解决。
我会选择方法#1:即在STL 容器中存储指向对象的智能指针。
请注意,可以在 STL 容器中存储非拥有的原始指针(例如观察原始指针),但存储拥有的原始指针是一种“泄漏”:使用shared_ptr
或新的 C++11unique_ptr
代替。
至于 #2,从头开始编写自己的容器需要大量时间和精力,而且我相信您无法在合理的时间范围内匹配完整的商业质量 STL 库实现的丰富性。