我使用的几个代码库包括手动调用的类,new
并delete
采用以下模式:
class Worker {
public:
void DoWork(ArgT arg, std::function<void()> done) {
new Worker(std::move(arg), std::move(done)).Start();
}
private:
Worker(ArgT arg, std::function<void()> done)
: arg_(std::move(arg)),
done_(std::move(done)),
latch_(2) {} // The error-prone Latch interface isn't the point of this question. :)
void Start() {
Async1(<args>, [=]() { this->Method1(); });
}
void Method1() {
StartParallel(<args>, [=]() { this->latch_.count_down(); });
StartParallel(<other_args>, [=]() { this->latch_.count_down(); });
latch_.then([=]() { this->Finish(); });
}
void Finish() {
done_();
// Note manual memory management!
delete this;
}
ArgT arg_
std::function<void()> done_;
Latch latch_;
};
现在,在现代 C++ 中,显式delete
是一种代码味道,在某种程度上是delete this
. 但是,我认为这种模式(创建一个对象来表示由回调链管理的一大块工作)基本上是一个好主意,或者至少不是一个坏主意。
所以我的问题是,我应该如何重写这种模式的实例来封装内存管理?
我认为不是一个好主意的一个选择是将其存储Worker
在shared_ptr
: 中,从根本上说,这里不共享所有权,因此引用计数的开销是不必要的。此外,为了shared_ptr
在回调中保持活动的副本,我需要继承 from enable_shared_from_this
,并记住在 lambda之外调用它并将 捕获shared_ptr
到回调中。如果我曾经直接使用写过简单的代码this
,或者shared_from_this()
在回调 lambda 中调用,那么该对象可能会被提前删除。