使用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>
的对象的构造函数中添加某种静态断言,以便在编译时而不是运行时提取该对象而非作为std::shared_ptr
的任何构造?
以下带有create
-函数的代码对我来说毫无例外。
#include <memory>
class X : public std::enable_shared_from_this<X> {
private:
X() = default;
public:
static std::shared_ptr<X> makeX() {
return std::shared_ptr<X>(new X());
}
void doSth() {
auto sharedPtr = shared_from_this();
// do sth
}
};
int main() {
auto x = X::makeX();
x->doSth();
}