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也不符合您的要求。@user441521
void 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));