如何防止删除用作共享指针的原始指针?
How to prevent deletion of a raw pointer that is used as shared pointer?
我为 C++ class 实现了 C-API,它使用其他对象的共享指针来访问它们。
在我的 C-API 中,我当然只能得到原始指针。
所以我 "convert" 我的 C-API 中的原始指针指向共享指针,然后将其与我的 C++ class 方法一起使用:
method(std::shared_ptr<dataType>(raw-pointer));
现在我遇到的问题是在 "method" 结束时总是调用共享指针析构函数,不幸的是它杀死了我的原始指针指向的对象(我不想要)。
那么,如何防止原始指针被杀死?
我已经尝试过像 reset() 或 swap() 这样的共享指针函数,但它们都没有让我的原始指针消失...
bool Traffic_doStep(traffic_handle t, environment_handle e, double cycletime) {
if (!valid(t, __FUNCTION__)) return false;
if (!valid(e, __FUNCTION__)) return false;
if (!valid(cycletime, __FUNCTION__)) return false;
try {
t->doStep(std::shared_ptr<Environment>(e), cycletime);
return true;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return false;
}
}
预期结果是原始指针 e 在此函数返回后仍指向有效对象。
实际上,原始指针然后指向一个已删除的对象。
不要把指针放在std::shared_ptr
C++ 中智能指针的目的是提供自动生命周期管理。当你写 std::shared_ptr<int> ptr{raw_ptr};
时,期望的是当 ptr
超出范围时,raw_ptr
指向的对象将是 delete
'。如果这不是本意,那么您不应该将指针放在智能指针中。
因此,如果您的应用程序不管理指针的生命周期,那么存储原始指针是完全可以接受的。
如果函数后面的API不能改变,你需要构造一个空操作删除函数的std::shared_ptr
,这样当clean-up被调用时,什么都不会发生在指针上。
try {
std::shared_ptr<Environment> temp_ptr{e, [](int *) {}/*No-Op Deleter*/};
t->doStep(temp_ptr, cycletime);
return true;
}
这将解决您的问题,但这当然是一个反模式;不要这样做,除非你被 API 你无法控制的设计限制所迫。
您可以提供共享指针的自定义删除器。
这是一个可行的构造函数:
template< class Y, class Deleter >
shared_ptr( Y* ptr, Deleter d );
但我宁愿使用一个唯一的指针,然后释放它。
我为 C++ class 实现了 C-API,它使用其他对象的共享指针来访问它们。 在我的 C-API 中,我当然只能得到原始指针。 所以我 "convert" 我的 C-API 中的原始指针指向共享指针,然后将其与我的 C++ class 方法一起使用:
method(std::shared_ptr<dataType>(raw-pointer));
现在我遇到的问题是在 "method" 结束时总是调用共享指针析构函数,不幸的是它杀死了我的原始指针指向的对象(我不想要)。 那么,如何防止原始指针被杀死?
我已经尝试过像 reset() 或 swap() 这样的共享指针函数,但它们都没有让我的原始指针消失...
bool Traffic_doStep(traffic_handle t, environment_handle e, double cycletime) {
if (!valid(t, __FUNCTION__)) return false;
if (!valid(e, __FUNCTION__)) return false;
if (!valid(cycletime, __FUNCTION__)) return false;
try {
t->doStep(std::shared_ptr<Environment>(e), cycletime);
return true;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return false;
}
}
预期结果是原始指针 e 在此函数返回后仍指向有效对象。 实际上,原始指针然后指向一个已删除的对象。
不要把指针放在std::shared_ptr
C++ 中智能指针的目的是提供自动生命周期管理。当你写 std::shared_ptr<int> ptr{raw_ptr};
时,期望的是当 ptr
超出范围时,raw_ptr
指向的对象将是 delete
'。如果这不是本意,那么您不应该将指针放在智能指针中。
因此,如果您的应用程序不管理指针的生命周期,那么存储原始指针是完全可以接受的。
如果函数后面的API不能改变,你需要构造一个空操作删除函数的std::shared_ptr
,这样当clean-up被调用时,什么都不会发生在指针上。
try {
std::shared_ptr<Environment> temp_ptr{e, [](int *) {}/*No-Op Deleter*/};
t->doStep(temp_ptr, cycletime);
return true;
}
这将解决您的问题,但这当然是一个反模式;不要这样做,除非你被 API 你无法控制的设计限制所迫。
您可以提供共享指针的自定义删除器。
这是一个可行的构造函数:
template< class Y, class Deleter >
shared_ptr( Y* ptr, Deleter d );
但我宁愿使用一个唯一的指针,然后释放它。