【发布时间】:2020-05-06 08:17:29
【问题描述】:
在使用std::shared_ptr 时,使用std::enable_shared_from_this<T> 通常很有用,这样您就可以访问shared_from_this() 函数。
使用shared_from_this() 的一个要求是对象的所有实例都使用std::shared_ptr 构造。虽然这是一个非常好的要求,但对于该课程的未来用户强制感觉非常困难。
如果我创建一个对象:
class MyClass : public std::enable_shared_from_this<MyClass>
{
public:
MyClass()
{
}
void doAThing()
{
// something I need done asynchronously
}
void someFunction()
{
std::weak_ptr<MyClass> w (shared_from_this());
// we need to use a lambda that is executed asynchronously and
// so we pass the std::weak_ptr to it to check this object still exists it is executed
std::function<void()> f = [w]()
{
if (! w.expired())
w.lock()->doAThing();
};
callAsynchronously (f); // this function passes the lambda to some queue and executes it asynchronously
}
};
然后有人 - 可能是几年后 - 使用这个类而不将其构造为 shared_ptr...
MyClass m;
m.someFunction();
然后我们会遇到运行时崩溃:
libc++abi.dylib: terminating with uncaught exception of type std::__1::bad_weak_ptr: bad_weak_ptr
明确地说,我理解这个问题的解决方案是:
std::shared_ptr<MyClass> m = std::make_shared<MyClass>();
m->someFunction();
(当然需要确保shared_ptr 存在足够长的时间以使异步回调执行,但我在这里忽略了这一点)。
我的问题是 - 我们如何在继承自 std::enable_shared_from_this<T> 的对象的构造函数中添加某种静态断言,以便将该对象 not 构造为 std::shared_ptr在编译时而不是在运行时获取?
【问题讨论】:
-
您可以将
MyClass构造函数设为私有并添加返回std::shared_ptr<MyClass>的静态函数 -
我试过了,但是当我尝试使用
shared_from_this()时,我得到了一个错误的访问权限(除非我做错了)。另外,如果可能的话,我可以继续使用普通的构造函数。 -
@AdamStark 我认为这是不可能的,因为
make_shared或shraer_ptr::shared_ptr调用的构造函数不知道它被这些函数调用。 -
是的,我担心这可能是答案。我希望有这样的东西:
static_assert (std::is_shared_ptr<MyClass> (this), "Please use a shared_ptr!");- 但也许它不存在...... -
没有什么好办法。私有 ctor 是有问题的,因为这意味着您不能从派生类中使用它,甚至对于最终类,您也不能使用
make_shared。
标签: c++ shared-ptr smart-pointers enable-shared-from-this