重置在 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 中的绑定一样。重要的是指针也指向什么,它被分配了新的并继续存在。
(我非常不确定问题标题的措辞。我希望它不会误导我,因为我真的不知道如何总结这一点。但我会尽力解释我的问题以及我可以。)
在一个项目中,有这样的东西(凭记忆写的,经过简化):
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 中的绑定一样。重要的是指针也指向什么,它被分配了新的并继续存在。