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

时间:2017-03-30 14:00:13

标签: c++ pointers lambda shared-ptr

(我对这个问题标题的措辞非常不确定。我希望它不会产生误导,因为我真的不知道如何总结这一点。但我&#39 ;我会尽力解释我的问题。)

在一个项目中,有类似的东西(从内存中编写并简化):

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的有效对象时,顾名思义,某些进程将被停止。在这种情况下,在执行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);
}

以上代码有效。但是,我不确定我是否已经处于未定义的行为状态&#34;领土,只是幸运。范围obj的范围已经结束了吗?或者lambda作为参数传递的事实有助于扩展其生命&#34 ;?如果这样做是安全的,如果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);
}

但这是我随机尝试的。我编写它时完全专注于删除共享指针所持有的对象。它有效,但我甚至不确定它是否只是迂回甚至有效。

这些尝试是否会在任何地方进行?还是我完全走错了路?或者我应该坚持使用全局变量?非常感谢有关如何解决这个问题的任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

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