的enable_shared_from_this
和shared_from_this
使用情况是清楚的,但我倾向于说,在大多数使用情况下,它可以赞成static
方法,可推动投下了shared_ptr
和然后从中创建一个新的shared_ptr
(与OP建议的方法非常类似,但是使用静态方法来支持创建新的shared_ptr
)。
的static
方法方法的优点是,你不会落于试图让shared_from_this
当有此实例没有基础shared_ptr
,与bad_weak_ptr
导致的错误。
缺点是空气污染指数是隐含询问主叫方拿出一个shared_ptr
,所以如果主叫方刚刚原始指针的情况下,他不能使用它(调用者可以创建从一个shared_ptr
原始指针并调用该方法,但他怎么知道原始的原始指针是否已被shared_ptr
管理?)。另一方面,如果用户手头有一个unique_ptr
,他应该确定将其转换为shared_ptr
以调用静态方法应该没问题。
在某种程度上,优势和劣势是同一枚硬币的两面。
我希望在大多数情况下,要求API与shared_ptr
(它已经依赖于某种方式)一起工作,而不是允许使用任何类型的指针,希望有一个管理的shared_ptr
它。这与使用不易以错误方式使用的API的建议相符。
这里是@RichardHodges给出的代码使用静态方法的方法,而不是使用enable_shared_from_this
(很好的例子!):
// code based on Richard Hodges example
template<class Handler>
void long_process_with_completion_handler(Handler done) {
std::thread([done] {
std::cout << "long process starts" << std::endl;
std::this_thread::sleep_for(2000ms);
done();
}).detach();
}
// without the need to inherit from std::enable_shared_from_this
struct Controller {
auto get_lock() const {
return std::unique_lock<std::mutex>(_mutex);
}
static void start(std::shared_ptr<Controller>& pcontroller) {
long_process_with_completion_handler(
[self = std::shared_ptr<Controller>(pcontroller)] {
auto lock = self->get_lock();
std::cout << "all complete" << std::endl;
});
}
mutable std::mutex _mutex;
};
int main() {
std::condition_variable controller_done;
std::mutex done_mutex;
bool is_controller_done = 0;
// make shared controller and start its processing
auto pcontroller = std::shared_ptr<Controller>{ new Controller,
[&](auto*p) {
delete p;
auto lock = std::unique_lock<std::mutex>(done_mutex);
is_controller_done = true;
std::cout << "controller destroyed" << std::endl;
lock.unlock();
controller_done.notify_all();
}};
Controller::start(pcontroller);
// destroy the controlling pointer. but our controller is still running...
pcontroller.reset();
auto lock = std::unique_lock<std::mutex>(done_mutex);
controller_done.wait(lock, [&]{ return is_controller_done;});
std::cout << "program ends" << std::endl;
}
代码:http://coliru.stacked-crooked.com/a/281b0ef6d1b31c56
'空A :: member_function(){some_other_function (shared_from_this()); }' –