重置在 lambda 函数中捕获的共享指针

Resetting a shared pointer captured in a lambda function

(我非常不确定问题标题的措辞。我希望它不会误导我,因为我真的不知道如何总结这一点。但我会尽力解释我的问题以及我可以。)

在一个项目中,有这样的东西(凭记忆写的,经过简化):

Class A {
private:
    boost::weak_ptr<SomeClassB> b;
public:
    static boost::shared_ptr<SomeClassB> StopSomeProcesses () {
        boost::shared_ptr<SomeClassB> temp (new SomeClassB());
        b = temp;
        return temp;
    }
}

现在在另一个项目中,我需要做类似下面的事情:

boost::shared_ptr<SomeClassB> obj;
void someFunction () {
    obj = A::StopSomeProcesses();

    auto callback = [](){
        //some other stuff here
        obj.reset();
    };
    NamespaceFromYetAnotherProject::DoSomething(callback);
}

这基本上是在 b 持有来自 A::StopSomeProcesses 的有效 object 时,顾名思义,一些进程将被停止。在这种情况下,进程在执行 DoSomething 时停止。最后,DoSomething 将调用 callback,其中 obj 被重置,停止的进程现在终于可以继续了。

我已经这样做了,而且很有效。但是,我想尽可能避免使用全局变量。我尝试执行以下操作:

void someFunction () {
    boost::shared_ptr<SomeClassB> obj;
    obj = A::StopSomeProcesses();

    auto callback = [&obj](){
        //some other stuff here
        obj.reset();
    };
    NamespaceFromYetAnotherProject::DoSomething(callback);
}

以上代码有效。但我不确定我是否已经在 "undefined behavior" 领域并且只是运气好。 obj的作用域不是已经结束了吗?或者 lambda 作为参数传递的事实是否有助于扩展其 "life"?如果这样做是安全的,那么如果 callback 是 运行 在另一个线程上是否会失去安全性?

我也试过这样做:

void someFunction () {
    boost::shared_ptr<SomeClassB> obj;
    obj = A::StopSomeProcesses();

    auto callback = [obj](){
        //some other stuff here
        boost::shared_ptr<SomeClassB> tempObj (new SomeClassB(*obj));
        tempObj.reset();
    };
    NamespaceFromYetAnotherProject::DoSomething(callback);
}

但这是我随机尝试的。我写它的时候完全专注于删除共享指针持有的 object 。它奏效了,但我什至不确定它是否只是迂回或有效。

这些尝试有进展吗?还是我完全走错了路?还是我应该坚持使用全局变量?对于如何解决此问题的任何帮助,我们将不胜感激。谢谢!

您正在使用 shared_ptr,StopSomeProcesses 将在内部分配它指向的内存。指针按值传递,因此 obj 的生命周期无关紧要。每个函数调用都会为它创建一个新副本,就像 lambda 中的绑定一样。重要的是指针也指向什么,它被分配了新的并继续存在。