C++ shared_from_this() 不会让 obj 被破坏
Posted
技术标签:
【中文标题】C++ shared_from_this() 不会让 obj 被破坏【英文标题】:C++ shared_from_this() is not letting obj get destructed 【发布时间】:2021-11-23 12:33:09 【问题描述】:我有以下一段代码,它正在创建一个简单的 Name 对象,并在其中创建另一个对象 Name,并带有 shared_from_this()
引用。当我从这里阅读
https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this
“有效地执行 std::shared_ptr(weak_this),其中 weak_this 是 enable_shared_from_this 的私有可变 std::weak_ptr 成员。”
我理解为 shared_from_this() 只是创建一个指向共享 obj 的弱指针。但我不认为这是运行时的情况。有效地创建了一个循环引用。
最后,我期待 Name obj 应该被破坏,但这不是因为引用计数器是 2。
有人可以帮我理解我应该如何使用enable_shared_from_this()
,它可以有效地清理名称 obj,一旦它失去参考。
#include <iostream>
#include <memory>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
struct Another;
struct Name : public std::enable_shared_from_this<Name>
std::string t;
int m, n, p;
shared_ptr<Another> ann;
Name()
std::cout << "constructor\n";
void MakeSomething()
ann = std::make_shared<Another>(shared_from_this());
~Name()
std::cout << "destructor\n";
;
struct Another
shared_ptr<Name> nn;
Another(shared_ptr<Name> n) : nn(n)
std::cout << "from another constructor " << nn.use_count() << "\n";
~Another()
std::cout << "from another destructor\n";
;
int main()
auto n = std::make_shared<Name>();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
auto p = n.get();
//delete p;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
n->MakeSomething();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
shared_ptr<Name> m = n;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
std::cout << "Name ref count so far: " << n.use_count() << "\n";
// problem: at this point Name obj, should go out of reference and destructor to be called, which is NOT happening
return 0;
这是运行时输出(编译器使用 msvc)
constructor
Name ref count so far: 1
Name ref count so far: 1
from another constructor 3
Name ref count so far: 2
Name ref count so far: 3
Name ref count so far: 2
【问题讨论】:
你有一个 shared_ptrs 的循环引用。它们永远不会超出范围,因为它们相互指向。 @Yksisarvinen 是的,我知道。shared_from_this
正在创建循环引用,当在文档中说它正在创建弱引用时。正确的使用方式应该是什么shared_from_this
您可能需要让其中一个使用 std::weak_ptr
与shared_from_this
无关。你有两个shared_ptr
s,都指向对方。他们无法自行释放,因为任何一方都没有结束生命的时刻。您需要手动释放 (reset()
) 其中一个来打破圈子。或者其中之一不能是shared_ptr
,而是weak_ptr
或原始的、非拥有的指针。
"shared_from_this
正在创建循环引用" -- 不,是 您 创建了循环引用。如果函数shared_from_this
被单独调用(未分配给某物),它会返回一个立即销毁的临时对象。它需要您的 ann
和 nn
成员来创建循环引用。 shared_from_this
所做的只是简化创建循环引用的代码;它不是该代码的重要组成部分。
【参考方案1】:
我理解为 shared_from_this() 只是创建一个指向共享 obj 的弱指针。但我不认为这是运行时的情况。有效地创建了一个循环引用。
shared_from_this()
正在创建一个 weak_ptr
,您将其传递给一个 shared_ptr
构造函数,由 (11) here 指定。该构造函数为同一个对象创建了一个shared_ptr
,从而增加了引用计数。
还请记住,weak_ptr
根本不会影响引用计数,因此它不会影响您对引用计数的混淆。关注shared_ptr
s 正在做什么。
【讨论】:
以上是关于C++ shared_from_this() 不会让 obj 被破坏的主要内容,如果未能解决你的问题,请参考以下文章
在 lambda 函数中使用 auto self(shared_from_this()) 变量的原因是啥?
shared_from_this使用boost :: asio抛出bad_weak_ptr
为什么调用shared_from_this调用std :: terminate
使用 shared_from_this 参数等待 std::future 获取 std::async 会阻止对 this 的破坏
shared_from_this()如何在派生类中工作,该派生类继承自从enabled_shared_from_this继承的基类