如何正确使用 std::shared_from_this 或绕过它
How to properly use std::shared_from_this or trick around it?
给C++专家的问题:我有一个期望shared_ptr<T>
的库函数,我想在T
内调用这个函数。我知道share_from_this
是正确的方法,但我无法理解它(以及如何正确使用它)。
我想出了一个技巧,我想知道它是否安全(没有 UB)。如果不是,你能解释一下如何在我的情况下使用share_from_this
吗?
#include <memory>
template<class T>
void library_function(std::shared_ptr<T>)
{}
struct A {
std::shared_ptr<A> share()
{
return std::shared_ptr<A>(this, [](A*){});
}
void operator()()
{
library_function(share());
}
};
int main()
{
A a;
a();
}
首先,你想要share_from_this
的对象需要是之前共享的对象,并由 std::shared_ptr 管理。确保允许它的类需要从std::enable_shared_from_this<A>
公开继承。接下来,如果要从中创建共享指针,则需要使用方法 shared_from_this()
。
使用您当前的代码,它是安全的。
但是,如果library_function
存储shared_ptr
以后使用,并且a
由于超出范围而被销毁。这是未定义的行为。那就不安全了。此示例代码与您的代码没有太大区别,但它在第二次调用中具有未定义的行为:
template<class T>
void library_function(std::shared_ptr<T> t)
{
static std::shared_ptr<T> s;
if (!s) {
s = t;
}
if (s) s->do_something();
}
struct A {
std::shared_ptr<A> share()
{
return std::shared_ptr<A>(this, [](A*){});
}
void operator()()
{
library_function(share());
}
void do_something() {
}
};
int main()
{
// This emulates some function call and go out of scope
{
A a;
a();
}
// This call is undefined behavior
library_function(std::shared_ptr<A>{});
}
正确的方法是这样的:
#include <memory>
#include <iostream>
template<class T>
void library_function(std::shared_ptr<T> t)
{
static std::shared_ptr<T> s;
if (!s) {
s = t;
}
if (s) s->do_something();
}
struct A : std::enable_shared_from_this<A> {
~A() {std::cout << "Destructedn"; }
std::shared_ptr<A> share()
{
return shared_from_this();
}
void operator()()
{
library_function(share());
}
void do_something() {
std::cout << "do_somethingn";
}
};
int main()
{
// This emulates some function call and go out of scope
{
std::shared_ptr<A> a = std::make_shared<A>();
(*a)();
}
library_function(std::shared_ptr<A>{});
}
你应该从 std::enable_shared_from_this
派生你的类。确保您的对象由 std::shared_ptr
管理。
#include <memory>
template<class T>
void library_function(std::shared_ptr<T>)
{}
struct A : public std::enable_shared_from_this<A> {
void operator()()
{
library_function(shared_from_this());
}
};
int main()
{
auto a = std::make_shared<A>();
a->operator()();
}
你的类应该派生自 std::enable_shared_from_this<>
,然后你可以调用this->shared_from_this()
来获取它的shared_ptr<>
。
例如:
class foo : std::enable_shared_from_this<foo> {
public:
void bar() {
call_some_func(this->shared_from_this());
}
};
因此,call_some_func()
将收到指向foo
实例的共享指针。这将起作用,因为原始实例已经在共享指针中,即实例创建为:
auto foo_inst = std::make_shared<foo>();
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 为什么使用 "this" 指针调用派生成员函数?
- 如何解决"invalid conversion from 'char' to 'const char*'"
- C++错误:"error: int aaa::bbb is protected within this context"
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 关于C++中具有多重继承"this"指针的说明
- 在noexcept 规范中是否允许使用"this"?
- 如何修复"error: ‘_1’ was not declared in this scope"?
- C++调用具有 *this 属性的单个帮助程序函数
- Doees the 'this' 指针参与虚函数的多态行为
- 在 c++ 中正确定义"this"关键字?
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- std::async from std::async in windows xp
- QObject::连接无法将信号连接到*this*对象的插槽
- 析构函数中的"delete this"
- 为什么成员函数内的"this"指针为空?
- 为什么我需要在转换构造函数上引用 this->?
- G++ 编译错误"... is protected from within this context"而 clang 没有错误