C++ 打印shared_ptr树中的使用计数
C++ Printing shared_ptr use count in tree
我很难弄清楚为什么当我以不同的方式打印树时,我的共享指针会得到不同数量的 use_counts((。
使用下面的代码,当我调用方法"one->Print(("时,我似乎错误地为一个的直系子级获取了 2 个引用,但是当使用"one->Print(one("时,我得到了正确数量的引用,即 1。
如何更改我的代码,以便"one->Print(("为树中的所有节点返回正确数量的引用?
#include <iostream>
#include <memory>
template<class T> using sp = std::shared_ptr<T>;
struct Node {
int value;
sp<Node> child;
Node(int value): value {value} {}
inline void Print() const {
Print(std::make_shared<Node>(*this));
}
inline void Print(const sp<Node>& ptr) const {
Print(ptr, "", false);
}
void Print(const sp<Node>& ptr, const std::string& prepend, bool isEnd) const {
if(ptr != nullptr) {
std::cout << prepend << (isEnd ? "└────" : "├────");
std::cout << " " << ptr->value << " (" << ptr.use_count() << ")" << std::endl;
} else {
std::cout << " " << ptr->value << std::endl;
}
if(ptr->child != nullptr) {
Print(ptr->child, prepend + (isEnd ? " " : "│ "), false);
}
}
};
int main(int argc, char * argv[])
{
sp<Node> one = std::make_shared<Node>(1);
one->child = std::make_shared<Node>(2);
one->child->child = std::make_shared<Node>(3);
one->child->child->child = std::make_shared<Node>(4);
one->child->child->child = std::make_shared<Node>(5);
one->Print();
one->Print(one);
return 0;
}
输出如下所示:
one->打印((;
├──── 1 (1)
│ └──── 2 (2)
│ └──── 3 (1)
│ └──── 5 (1)
一>打印(一(;
├──── 1 (1)
│ └──── 2 (1)
│ └──── 3 (1)
│ └──── 5 (1)
这是因为您使用std::make_shared<Node>(*this)
创建*this
的副本(one
(,这将复制this->child
(one->chile
(并增加引用计数器。
你想要的可能是从enable_shared_from_this
继承并使用shared_from_this
,那么你会得到
├──── 1 (2)
│ └──── 2 (1)
│ └──── 3 (1)
│ └──── 5 (1)
更重要的是,如果你
不需要引用计数器(通常是真的(,如果你不打算管理资源,你不需要智能指针,你可以简单地接受一个Node*
。实际上,您可以使用this
并删除此示例中的所有指针。
示例代码。(使用this
代替ptr
(
struct Node: std::enable_shared_from_this<Node> {
int value;
sp<Node> child;
Node(int value): value {value} {}
void Print() const {
Print("", false);
}
void Print(const std::string& prepend, bool isEnd) const {
std::cout << prepend << (isEnd ? "└────" : "├────");
std::cout << " " << this->value << " (" << shared_from_this().use_count()-1 /*remove current count*/ << ")" << std::endl;
if(this->child) {
this->child->Print(prepend + (isEnd ? " " : "│ "), false);
}
}
};
你也可以使用week_from_this
(c++17(,魔杖盒示例
当你调用 Print(ptr)
时,它会作为对共享指针的引用传递,并且不会进行复制。
当您调用 Print()
时,它会创建共享指针的副本并将其传递给Print(ptr)
。
正是该副本增加了引用计数。如果您不希望发生这种情况,请不要复制。您应该能够直接传递this
作为参考。
如其他答案中所述,通过调用std::make_shared<Node>(*this)
,您实际上是在调用默认的复制构造函数。因此命中newObj->child = (*this).child
某处(即 - std::shared_ptr 的重载 =(赋值运算符(,从而将引用计数增加到 2。当函数Print()
退出时,shared_ptr被销毁,从而将引用计数减少到 1。
当您使用引用调用时,不会创建任何内容,因此您会看到预期的结果。
解决此问题的一种方法是重载函数以接受const Node &
然后可以使用*this
。
- 如何循环打印顶点结构
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 如何在c++中打印目录
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 在线编译器中的分段C++没有打印消息
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 如何将结构插入到集合中并打印集合的成员
- 在循环C++中指定字符串之后,不会打印该字符串
- 以螺旋方式打印矩阵的程序.(工作不好)
- 从控制台中删除最后打印的元素
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何仅使用对象名称打印特定于对象的成员
- 回溯C++不打印函数,因此文件
- 在一定长度后从数组中打印时缺少整数
- 为什么这个 c++ 代码打印出长度 5,当我打印出字符串时,程序会自动终止?
- 在gem5中打印文件中的所有cache_blocks
- 打印数字图案
- Log4cpp:以UTC/GMT时区打印日期
- 如何使用gdb制作一个可以漂亮地打印每个对象的C++函数