【发布时间】: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_ptrs,都指向对方。他们无法自行释放,因为任何一方都没有结束生命的时刻。您需要手动释放 (reset()) 其中一个来打破圈子。或者其中之一不能是shared_ptr,而是weak_ptr或原始的、非拥有的指针。 -
"
shared_from_this正在创建循环引用" -- 不,是 您 创建了循环引用。如果函数shared_from_this被单独调用(未分配给某物),它会返回一个立即销毁的临时对象。它需要您的ann和nn成员来创建循环引用。shared_from_this所做的只是简化创建循环引用的代码;它不是该代码的重要组成部分。
标签: c++ c++11 visual-c++ c++17 c++14