C++ 从内部功能中移除智能ptr
有没有办法从函数中销毁C++ 从内部功能中移除智能ptr,c++,smart-pointers,C++,Smart Pointers,有没有办法从函数中销毁std::shared_ptr?在下面的示例中,如果我在main()中将sptr设置为nullptr,它将“销毁”对象,因此调用它的Print()失败。但是,在Delete()函数中这样做并不能做到这一点。当它传入时,猜测它会增加它的ref计数。我明白了,但是有没有办法覆盖它并减少Delete()中的ref计数,所以在这种情况下,obj=nullptr会破坏它 我知道这通常不是您想要做的,但在这种情况下,外部脚本语言需要能够调用函数来实际销毁指向的对象,因此使用Delete
std::shared_ptr
?在下面的示例中,如果我在main()
中将sptr
设置为nullptr
,它将“销毁”对象,因此调用它的Print()
失败。但是,在Delete()
函数中这样做并不能做到这一点。当它传入时,猜测它会增加它的ref计数。我明白了,但是有没有办法覆盖它并减少Delete()
中的ref计数,所以在这种情况下,obj=nullptr
会破坏它
我知道这通常不是您想要做的,但在这种情况下,外部脚本语言需要能够调用函数来实际销毁指向的对象,因此使用Delete(obj)
是理想的
#include <memory>
#include <string>
#include <iostream>
using namespace std;
class Test{
private:
string name;
public:
Test(string _name) { name = _name; }
void Print() const { cout << name; }
};
void Delete(std::shared_ptr<Test> obj)
{
obj = nullptr;
}
int main(){
shared_ptr<Test> sptr(new Test("Test"));
Delete(sptr);
//sptr = nullptr;
sptr.get()->Print();
}
#包括
#包括
#包括
使用名称空间std;
课堂测试{
私人:
字符串名;
公众:
测试(字符串_name){name=_name;}
void Print()常量{cout Print();
}
通过值传递无效删除(共享对象)
进行复制,这会增加sptr
的计数器,因此nullptr
的赋值会减少计数器,但不会破坏底层对象。您可以通过引用传递无效删除(共享对象)
如果您想在删除函数中取消禁用共享\u ptr
。我想使用std::move
是更好的选择
void Delete(shared_ptr<Test>&& obj) //rvalue reference
{
obj = nullptr;
}
调用后,使用std::move
转移资源的所有权,并且不能在main
中进一步使用。通过引用传递它?尝试了void Delete(shared_ptr*obj){},Delete(&sptr);。没有工作obj.reset()
而不是obj=nullptr;
无论如何,这样愚蠢的事情没有意义。obj->reset()
可以使用指针类型。或者obj.reset()
可以使用引用类型。通过值传递smart\u ptr也不符合您的要求。@user441521void Delete(shared\u ptr&obj){obj.reset();}
这确实有效。是否不赞成调用。\u Decref()这似乎也可以。不过我猜他们也在做同样的事情?@user441521是\u Decref
在std::shared\u ptr
中定义的一个实现辅助函数。不要使用它。它不是你想要使用的。使用标准中记录的方法。@user441521不过,你可以出于兴趣而尝试,b但是首先想想当main
中的sptr
超出范围时会发生什么?看起来.reset()基本上也在做同样的事情。减少了对象上的1个所有者(ref count)。我想可以使用use_count()(?)循环检查有多少个引用并调用reset()很多时候要真正删除对象。@ USSR151521不要这样做。它不应该被这样使用。如果你认为你真的需要这个,你应该检查你的应用程序的架构。<代码> SydDypTr> /Cult>被称为共享,因为所有权是共享的。也许你可以考虑使用<代码> UnQuyPPTR < /代码>。“使用std::move
转移了资源的所有权”并不确切地说,std::move
只是一个演员阵容。所有作品都发生在obj=nullptr
中(因为obj
是一个(右值-)参考)。
Delete(std::move(sptr));