C++ 如果涉及“this”,则无法在构造函数中初始化共享\u ptr
我有一些代码的结构如下:C++ 如果涉及“this”,则无法在构造函数中初始化共享\u ptr,c++,shared-ptr,C++,Shared Ptr,我有一些代码的结构如下: #include <memory> #include <vector> using namespace std; struct demo { vector<shared_ptr<demo>> foo{shared_ptr<demo>(this)}; void append(){ foo.push_back(make_shared<demo>()); } };
#include <memory>
#include <vector>
using namespace std;
struct demo {
vector<shared_ptr<demo>> foo{shared_ptr<demo>(this)};
void append(){
foo.push_back(make_shared<demo>());
}
};
demo dummy(/* accept some arguments */){
demo a{};
a.append();
return a;
}
int main()
{
demo bar=dummy();
return 0;
}
然后它就起作用了。但我仍然想知道这些线背后的机制。请解释一下新构建的
变量和通常声明的变量之间的区别好吗
EDIT:那么最后还有什么方法可以
将这个
推回到向量中,作为其构造函数中的结构成员?(出于这个原因,这是因为我的向量的其余部分存储了除第一个之外的所有shared\u ptr
,换句话说,即使向量pop\u back
ed为空,它仍然可以返回this
)在堆栈上创建a
,或者让ashared\u ptr
管理它的生存期,但你不能两者兼而有之。当堆栈消失时,堆栈上的对象也会消失。在堆栈上创建a
,或者让shared\u ptr
管理其生存期,但不能同时执行这两项操作。当堆栈消失时,堆栈上的对象也会消失。下面是一个更简单的示例,它再现了您的问题:
struct demo {
shared_ptr<demo> foo{this};
};
int main()
{
demo bar;
}
这样更好,因为现在对象(由条指向)具有动态存储,因此您可能有一个指向它的共享指针。当然,您必须修复dummy
,才能不创建自动demo
实例
此外,您不能明确地删除演示的实例,因为其中有一个指向自身的共享。处置demo
实例的“正确”方法是删除共享指针,然后删除:
demo* bar=new demo(dummy());
bar->foo.clear(); // this is for your vector version
//bar->foo = nullptr; // this is for my minimized example above
// object pointed by bar no longer exists
// (unless the shared pointer was copied and exists elsewhere)
然而,我发现这种设计非常令人困惑,因此不推荐它。您应该重新考虑为什么要存储指向此
的共享指针这里有一个更简单的示例,它再现了您的问题:
struct demo {
shared_ptr<demo> foo{this};
};
int main()
{
demo bar;
}
这样更好,因为现在对象(由条指向)具有动态存储,因此您可能有一个指向它的共享指针。当然,您必须修复dummy
,才能不创建自动demo
实例
此外,您不能明确地删除演示的实例,因为其中有一个指向自身的共享。处置demo
实例的“正确”方法是删除共享指针,然后删除:
demo* bar=new demo(dummy());
bar->foo.clear(); // this is for your vector version
//bar->foo = nullptr; // this is for my minimized example above
// object pointed by bar no longer exists
// (unless the shared pointer was copied and exists elsewhere)
然而,我发现这种设计非常令人困惑,因此不推荐它。您应该重新考虑为什么存储指向的共享指针,该条不会自动删除:demo*bar=newdemo(dummy())代码>它会泄漏。你应该避免共享\u ptr(this)
(因为你以前没有谁拥有这个
的保证)从中启用共享\u这个
可能会有帮助。你不能拿一个别人独占的对象并决定它是共享的。分享必须是双方的协议,否则事情可能会严重出错。@molbdnilo:我在哪里做的?(我不是那个意思)@YiFeishared\u ptr(this)
就是这么做的。您可以使用std::enable_shared_from_this
和std::shared_from_this
来获取共享的ptr
,但即使如此,此
必须已经由std::shared_ptr
管理bar
不会自动删除:demo*bar=new demo(dummy())代码>它会泄漏。你应该避免共享\u ptr(this)
(因为你以前没有谁拥有这个
的保证)从中启用共享\u这个
可能会有帮助。你不能拿一个别人独占的对象并决定它是共享的。分享必须是双方的协议,否则事情可能会严重出错。@molbdnilo:我在哪里做的?(我不是那个意思)@YiFeishared\u ptr(this)
就是这么做的。您可以使用std::enable_shared_from_this
和std::shared_from_this
获得shared_ptr
,但即使如此,this
必须已经由std::shared_ptr
管理。完全同意未定义的行为解释。但在我尝试时,代码并没有重现我的问题(编译并运行),我个人认为问题在于函数。你说的“bar
is和automatic variable”是什么意思?@YiFei我的意思是变量有存储期限。我的示例可能与您的示例不具有相同的行为,因为该行为未定义。然而,它显示了相同的错误。注意,为了更好的通用性,我将“variable”更改为“object”。如果我将这些共享的\u ptr存储在外部(关于结构的实例,比如在main函数中)会更好吗容器还是只存储裸指针?@YiFei如果你没有描述为什么要使用共享指针,很难说什么更好。如果您确实希望维护指向*bar
的共享指针,那么是的,您应该在main中使用共享指针。是的,如果您在一个成员中存储了此
的副本,那么该指针应该是空的。尽管如此,如果向量中的所有指针都应该由共享指针维护,弱指针也可能是一个选项。完全同意未定义的行为解释。但在我尝试时,代码并没有重现我的问题(编译并运行),我个人认为问题在于函数。你说的“bar
is和automatic variable”是什么意思?@YiFei我的意思是变量有存储期限。我的示例可能与您的示例不具有相同的行为,因为该行为未定义。然而,它显示了相同的错误。注意,为了更好的通用性,我将“variable”更改为“object”。如果我将这些共享的\u ptr存储在外部(关于结构的实例,比如在main函数中)会更好吗容器还是只存储裸指针?@YiFei如果你没有描述为什么要使用共享指针,很难说什么更好。如果您确实希望维护指向*bar
的共享指针,则