shared_array元素作为shared_ptr
Element of shared_array as shared_ptr?
如果我有一个boost::shared_array<T>
(或boost::shared_ptr<T[]>
(,有没有办法获得与数组共享的boost::shared_ptr<T>
?
例如,我可能想写:
shared_array<int> array(new int[10]);
shared_ptr<int> element = &array[2];
我知道我不能使用 &array[2]
,因为它只有类型 int *
,对于shared_ptr<int>
来说,拥有一个将采用该类型的隐式构造函数是危险的。理想情况下,shared_array<int>
将有一个实例方法,如下所示:
shared_ptr<int> element = array.shared_ptr_to(2);
不幸的是,我找不到这样的东西。shared_ptr<int>
上有一个混叠构造函数,它将与另一个shared_ptr<T>
混叠,但它不允许与shared_array<T>
混叠;所以我也不能写这个(它不会编译(:
shared_ptr<int> element(array, &array[2]);
//Can't convert 'array' from shared_array<int> to shared_ptr<int>
我玩的另一个选择是使用std::shared_ptr<T>
(std
而不是boost
(。T[]
的专业化不是标准化的,所以我考虑自己定义它。不幸的是,我认为这实际上是不可能的,因为它试图将我的std::shared_ptr<T[]>
转换为它自己的特定于实现的超类型,这不再可能。(我的目前只是从助推器继承而来。这个想法的好处是我可以shared_ptr_to
方法实现我的实例。
这是我尝试过的另一个想法,但我认为它不够有效,不足以作为我们可能在整个大型项目中使用的东西。
template<typename T>
boost::shared_ptr<T> GetElementPtr(const boost::shared_array<T> &array, size_t index) {
//This deleter works by holding on to the underlying array until the deleter itself is deleted.
struct {
boost::shared_array<T> array;
void operator()(T *) {} //No action required here.
} deleter = { array };
return shared_ptr<T>(&array[index], deleter);
}
我要尝试的下一件事是升级到 Boost 1.53.0(我们目前只有 1.50.0(,使用 shared_ptr<T[]>
而不是 shared_array<T>
,并且始终使用 boost
而不是 std
(即使对于非数组(。我希望这会起作用,但我还没有机会尝试它:
shared_ptr<int[]> array(new int[10]);
shared_ptr<int> element(array, &array[2]);
当然,我仍然更喜欢实例方法语法,但我想我对那个语法不走运(没有修改 Boost(:
shared_ptr<int> element = array.shared_ptr_to(2);
其他人有什么想法吗?
你在做奇怪的事情。为什么需要shared_ptr
元素?您是否希望将数组元素传递到其他地方并按住数组以防止删除?
如果是,那么std::vector<shared_ptr<T>>
更适合这样做。该解决方案是安全的、标准的,并且在移除对象时具有精细的粒度
boost::shared_ptr
似乎并不支持这一点。也许您可以使用自定义删除器解决此问题。但是std::shared_ptr
提供了一个特殊的构造函数来支持你想要的:
struct foo
{
int a;
double b;
};
int main()
{
auto sp1 = std::make_shared<foo>();
std::shared_ptr<int> sp2 (sp1,&sp1->a);
}
在这里,sp1
和sp2
共享foo
对象的所有权,但sp2
指向它的成员。如果sp1
被销毁,foo
对象仍将处于活动状态,并且sp2
仍然有效。
这是我最后所做的。
我自己实现了shared_array<T>
。它有效地扩展了shared_ptr<vector<T>>
,除了它实际上扩展了我自己的包装器vector<T>
,以便用户无法获取向量。这意味着我可以保证它不会被调整大小。然后我实现了我需要的实例方法 - 包括weak_ptr_to(size_t)
,当然还有operator[]
。
我的实现使用std::make_shared
来制作矢量。因此,向量将其内部数组存储与控制块分开分配,但向量本身成为控制块的成员。因此,这相当于忘记将std::make_shared
用于普通类型 - 但由于这些是数组,它们可能很大而且很少,所以它不太重要。
我还可以创建一个基于 shared_ptr<T>
但具有 default_delete<T[]>
或任何所需内容的实现,但它必须将数组与控制块分开分配(因此与矢量相比没有太多节省(。我认为没有一种便携式方法可以在控制块中嵌入动态大小的数组。
或者我的实现可以基于 boost::shared_array<T>
,并在获取元素指针时使用自定义删除器(根据问题中的示例(。在大多数情况下,这可能更糟,因为不是一次性命中分配数组,而是每次我们获取锯齿指针时都会受到命中(这对于非常短暂的指针可能会发生很多(。
我认为使其更加优化的唯一合理方法是使用最新的提升(如果它有效;在我改变主意之前,我没有尝试过,主要是因为对我自己的实例成员的渴望(。当然,这意味着在任何地方都使用boost
的,即使是单个对象。
但是,我使用的主要优点是Visual Studio的调试器(我被告知(擅长显示std::shared_ptrs和std::vectors的内容,并且(我们期望(不太擅长分析boost事物或自定义事物的内容。
所以我认为我所做的基本上是最佳的。 :)
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理