如何将原始指针包装到shared_ptr中,并防止shared_ptr删除对象
How to wrap a raw pointer into a shared_ptr and prevent shared_ptr from deleting the object?
我需要将原始指针包装到shared_ptr
中,以便将其传递给函数。函数返回后不再保存对输入对象的任何引用。
{
MyClass i;
shared_ptr<MyClass> p(&i);
f(p);
// BAD: shared_ptr will delete i.
}
如何阻止shared_ptr
删除引用的对象?
正如chris在评论中提到的,写一个空的delete:
#include <type_traits>
template <typename T>
struct empty_delete
{
empty_delete() /* noexcept */
{
}
template <typename U>
empty_delete(const empty_delete<U>&,
typename std::enable_if<
std::is_convertible<U*, T*>::value
>::type* = nullptr) /* noexcept */
{
}
void operator()(T* const) const /* noexcept */
{
// do nothing
}
};
使用示例:
#include <iostream>
#include <memory>
struct noisy
{
noisy() { std::cout << "alive" << std::endl; }
~noisy() { std::cout << "dead" << std::endl; }
noisy(const noisy&);
noisy& operator=(const noisy&);
};
template <typename T>
void take(T& yours)
{
std::cout << "Taking..." << std::endl;
{
auto mine = std::move(yours);
}
std::cout << "Took." << std::endl;
}
int main()
{
std::unique_ptr<noisy> a(new noisy());
std::shared_ptr<noisy> b(new noisy());
std::unique_ptr<noisy, empty_delete<noisy>> c(new noisy());
std::shared_ptr<noisy> d(new noisy(), empty_delete<noisy>());
take(a);
take(b);
take(c);
take(d);
}
输出:活着活着
活着
活着
把…
死
了。
把…
死
了。
把…
了。
把…
花了。
当然,这个例子泄漏了内存
对于评论中提到的。net/clr,您应该实现ref class
,传递托管句柄^
,并让垃圾收集器管理生命周期。
ref class MyClassManaged : public Pen
{
public:
MyClassManaged() : Pen{}, native_{ new MyClass{} } { }
~MyClassManaged() { this->!MyClassManaged(); }
!MyClassManaged() { delete native_; }
private:
MyClass* native_;
};
//...
{
MyClassManaged^ i = gcnew MyClassManaged{};
fManaged(i);
}
TL;DR只需保留shared_ptr<MyClass>
的另一个副本,如果仍然需要,将i
分配到堆上而不是堆栈上。
{
shared_ptr<MyClass> another_p;
{
MyClass i;
shared_ptr<MyClass> p(&i);
f(p);
// p has not deleted i yet
another_p = p; // increment reference count
// p will decrement the reference count
// i will be deleted due to stack unwinding
}
// another_p still holds a reference to where i was on the stack
if (another_p)
something(); // yes, something() will be invoked
else
nothing(); // no, nothing() won't run here
// another_p will attempt to delete again if not the shared_ptr is not copied elsewhere
}
场景2
{
shared_ptr<MyClass> another_p;
{
auto p = make_shared<MyClass>();
auto& i = *p;
f(p);
// p has not deleted i
another_p = p; // increment reference count
// p will decrement the reference count
// i will be NOT deleted
}
// another_p still holds a reference to where i was on the heap
if (another_p)
something(); // yes, something() will be invoked
else
nothing(); // no, nothing() won't run here
// another_p will attempt to delete again if not the shared_ptr is not copied elsewhere
}
// it will finally be deleted now
简单地保留另一个shared_ptr的副本;不需要使用空的删除器。
相关文章:
- 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用于资源管理