Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 共享_数组的元素作为共享_ptr?_C++_Boost_C++11_Shared Ptr - Fatal编程技术网

C++ 共享_数组的元素作为共享_ptr?

C++ 共享_数组的元素作为共享_ptr?,c++,boost,c++11,shared-ptr,C++,Boost,C++11,Shared Ptr,如果我有一个boost::shared_数组(或boost::shared_ptr),有没有办法获得与数组共享的boost::shared_ptr 例如,我可能想写: shared_array<int> array(new int[10]); shared_ptr<int> element = &array[2]; 不幸的是,我找不到这样的东西。shared_ptr上有一个别名构造函数,它将与另一个shared_ptr别名,但它不允许与shared_数组别名;所

如果我有一个
boost::shared_数组
(或
boost::shared_ptr
),有没有办法获得与数组共享的
boost::shared_ptr

例如,我可能想写:

shared_array<int> array(new int[10]);
shared_ptr<int> element = &array[2];
不幸的是,我找不到这样的东西。
shared_ptr
上有一个别名构造函数,它将与另一个
shared_ptr
别名,但它不允许与
shared_数组
别名;所以我也不能写这个(它不会编译):

接下来我将尝试升级到Boost 1.53.0(我们目前只有1.50.0),使用
shared_ptr
而不是
shared_array
,并且始终使用
Boost
而不是
std
(即使对于非数组)。我希望这会奏效,但我还没有机会尝试:

shared_ptr<int[]> array(new int[10]);
shared_ptr<int> element(array, &array[2]);
shared_ptr数组(新int[10]);
共享_ptr元素(数组和数组[2]);
当然,我仍然更喜欢实例方法语法,但我想我不太可能使用它(除了修改Boost):

shared_ptr element=array.shared_ptr_to(2);

还有人有什么想法吗?

你在做奇怪的事情。 为什么您需要
共享\u ptr
到元素?是否要将数组的元素传递到其他位置并阻止移除数组


如果是,则比
std::vector
更适合这样做。该解决方案是安全的、标准的,并且在对象删除方面具有很好的粒度

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);
}
structfoo
{
INTA;
双b;
};
int main()
{
自动sp1=std::使_共享();
std::shared_ptr sp2(sp1,&sp1->a);
}

这里,
sp1
sp2
共享
foo
对象的所有权,但
sp2
指向它的一个成员。如果
sp1
被销毁,则
foo
对象仍将处于活动状态,
sp2
仍将有效。

以下是我最后所做的

我自己实现了
共享_数组
。它有效地扩展了
shared\u ptr
,除了它实际上扩展了我自己的
vector
包装器,这样用户就无法取出向量。这意味着我可以保证它不会被调整大小。然后我实现了我所需要的实例方法,包括
weak\u ptr\u to(size\u t)
当然还有
operator[]

我的实现使用
std::make_shared
生成向量。因此,向量独立于控制块分配其内部阵列存储,但向量本身成为控制块的一个成员。因此,这相当于忘记对普通类型使用
std::make_shared
——但是因为这些是数组,它们可能是大而少的,所以就不那么重要了

我还可以创建一个基于
shared\u ptr
的实现,但是使用
default\u delete
或任何需要的东西,但是它必须与控制块分开分配数组(因此与矢量相比没有太多节省)。我不认为有一种可移植的方法可以在控制块中嵌入动态大小的数组

或者我的实现可以基于
boost::shared_array
,并在获取元素指针时使用自定义删除器(如问题中的示例所示)。在大多数情况下,这可能更糟糕,因为不是一次性命中分配数组,而是每次获取别名指针时都会命中一次(对于寿命很短的指针,这种情况可能会经常发生)

我认为让它变得更优化的唯一合理方法是使用最新的boost(如果它有效的话;在我改变主意之前,我没有尝试过它,主要是因为我对自己的实例成员的渴望)。当然,这意味着在任何地方都要使用
boost
one,即使对于单个对象也是如此

但是,我使用的主要优点是Visual Studio的调试器(听说)擅长显示std::shared_ptrs和std::vectors的内容,并且(我们期望)不太擅长分析boost内容或自定义内容


因此,我认为我所做的基本上是最佳的

你的想法是应该这样做的。它没有什么特别低效的地方(如果有疑问,请使用探查器运行一个实验)。@n.m.我认为它会为新的
共享\u ptr
创建一个新的控制块(在堆上)。虽然没有那么糟糕,但如果它可以共享同一个控制块,那就更好了。:)您是否需要一个
共享_数组
?如果您有一个
共享的\u ptr
(带有适当的deleter),您可以使用别名构造函数。我已经考虑过了。唯一缺少的就是
操作符[]
。我将发布一个答案,说明我最后做了什么。是的,我希望整个数组都能保留,只要我有一个指向任何元素的指针。这种情况会发生在API为了安全而采用共享的\u ptr时,但有时我们会同时分配许多类似的对象,并希望将堆开销降到最低。同时,应用程序的其余部分并不特别需要知道对象来自数组虽然,我认为弱ptr可能更适合这些情况,但当然,上述所有问题仍然适用,但在某些地方,稍微调整一下说弱ptr而不是共享ptr。@entheh那么数组的生存期呢,它什么时候发布呢?任何拥有数组共享ptr的对象都将负责该问题。但例如,有时我可能会将弱ptr带到元素,并将它们提供给Lua,并且总会有人意外地在Lua中保留对象太长时间。我们希望在这种情况下有明确的行为,仅此而已。)我不确定
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);
}
shared_ptr<int[]> array(new int[10]);
shared_ptr<int> element(array, &array[2]);
shared_ptr<int> element = array.shared_ptr_to(2);
struct foo
{
    int a;
    double b;
};

int main()
{
    auto sp1 = std::make_shared<foo>();
    std::shared_ptr<int> sp2 (sp1,&sp1->a);
}