我在以下情景中:
struct container {
data* ptr;
};
void someFunc(container* receiver /* wants to be filled */) {
auto myData = createData(); // returns shared_ptr<data>
receiver->ptr = myData.get();
}
生成该数据的函数以及接收它的对象是两个不同库的一部分,我无法修改它的源代码。我必须使用这些数据类型,我无能为力。
所以我必须实现一个获取一些数据的函数,然后将指向该数据的指针传递给一个对象。我的问题是创建我的数据的函数返回一个shared_ptr
实例。需要数据的对象只接受指向它的原始指针。
如您所见,我在get()
上调用shared_ptr
来获取原始指针并将其传递给接收对象。如果我没有弄错,那么只要shared_ptr
超出范围,shared_ptr
就会减少引用计数。所以在这种情况下,这意味着一旦函数返回它就会破坏我的数据,因为引用计数将达到0。
那么如何在不破坏托管对象的情况下摆脱shared_ptr
实例呢?我将数据传递给的对象(为了简单起见,用&#34;容器&#34; struct说明)确实在其析构函数中处理内存清理,所以我不需要任何引用计数或类似的东西。我不想要任何东西来监视分配的数据了(除了接收指向它的指针的对象)。我想摆脱{{1}},只有一个指向已分配数据的原始指针,我可以将其传递给接收对象。
这可能吗?
答案 0 :(得分:6)
static std::map m<data *, std::shared_ptr<data> >;
struct container {
data* ptr;
};
void someFunc(container* receiver /* wants to be filled */) {
auto myData = createData(); // returns shared_ptr<data>, I can't do anything about it
receiver->ptr = myData.get();
m[receiver->ptr] = myData;
}
void someOtherFunc(container* receiver)
{
// delete receiver->ptr;
m.erase(receiver->ptr);
}
通过地图延长了shared_ptr
的生命。
答案 1 :(得分:2)
std::shared_ptr
不会放弃所有权,因此您必须将其保留在类中的某个位置,以确保指针不会被删除。仍然,您可以使用获取的shared_ptr
而不是存储原始指针。原始指针几乎总是一个糟糕的选择。
答案 2 :(得分:2)
这是不可能的。
即使您在container
析构函数中处理对象破坏,也无法保证没有其他对象std::shared_ptr
持有指向该对象的指针(在这种情况下,您将看到{{1} }错误)。
如果对象生命周期由double free
管理(没有特殊删除器),那么您只能通过std::shared_ptr
和std::shared_ptr
来控制对象生存期。
答案 3 :(得分:1)
我能看到的唯一方法(如果你的设计允许)是包装你的容器:
struct container {
data* ptr;
};
struct container_wrapper {
std::shared_ptr<data> ptr; // ensure this lives as long as needed
container cnt;
};
void someFunc(container_wrapper& receiver /* wants to be filled */) {
receiver.ptr = createData();
receiver.cnt.ptr = receiver.ptr.get();
}