Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
共享指针不增加使用计数 我试图在C++中使用 STD::SyrdYPPTR 的想法。但是它非常混乱,我不知道如何创建指向同一对象的多个共享指针。即使是文档和在线材料也不是很清晰_C++_C++11_Shared Ptr_Reference Counting_Make Shared - Fatal编程技术网

共享指针不增加使用计数 我试图在C++中使用 STD::SyrdYPPTR 的想法。但是它非常混乱,我不知道如何创建指向同一对象的多个共享指针。即使是文档和在线材料也不是很清晰

共享指针不增加使用计数 我试图在C++中使用 STD::SyrdYPPTR 的想法。但是它非常混乱,我不知道如何创建指向同一对象的多个共享指针。即使是文档和在线材料也不是很清晰,c++,c++11,shared-ptr,reference-counting,make-shared,C++,C++11,Shared Ptr,Reference Counting,Make Shared,下面是我写的一小段代码,试图理解std::shared\u ptr的行为: #include <iostream> #include <memory> using namespace std; class Node { public: int key; Node() { key = 0; } Node(int k) { key = k; } }; int main() {

下面是我写的一小段代码,试图理解
std::shared\u ptr
的行为:

#include <iostream>
#include <memory>
using namespace std;

class Node
{
public:
    int key;
    Node()
    {
        key = 0;
    }
    Node(int k)
    {
        key = k;
    }
};

int main()
{
    Node node = Node(10);

    shared_ptr<Node> ptr1((shared_ptr<Node>)&node);
    cout << "Use Count: " << ptr1.use_count() << endl;

    // shared_ptr<Node> ptr2=make_shared<Node>(node);//This doesn't increase use_count
    shared_ptr<Node> ptr2((shared_ptr<Node>)&node);
    cout << "Use Count: " << ptr2.use_count() << endl;

    if (ptr1 == ptr2)
        cout << "ptr1 & ptr2 point to the same object!" << endl;

    if (ptr1.get() == ptr2.get())
        cout << "ptr1 & ptr2 point to the same address!" << endl;

    cout << "ptr1: " << ptr1 << "  "
         << "ptr2: " << ptr2 << endl;
    return 0;
}
#包括
#包括
使用名称空间std;
类节点
{
公众:
int键;
节点()
{
键=0;
}
节点(int k)
{
key=k;
}
};
int main()
{
节点=节点(10);
共享的ptr ptr1((共享的ptr)和节点);

如果单独创建
shared_ptr
s(包括使用
make_shared
),则使用计数不会增加,它们根本不共享。创建的
shared_ptr
对其他
shared_ptr
和正在管理的指针一无所知,甚至指针可能恰好是相同的(请注意,这可能导致多次破坏)

您需要告诉哪些
shared\u ptr
s应该被共享;当您从另一个
shared\u ptr
创建
shared\u ptr
时,使用计数会增加

shared_ptr<Node> ptr1 = make_shared<Node>(10);
cout<<"Use Count: "<<ptr1.use_count()<<endl; // 1

shared_ptr<Node> ptr2(ptr1);
cout<<"Use Count: "<<ptr2.use_count()<<endl; // 2
cout<<"Use Count: "<<ptr1.use_count()<<endl; // 2
shared_ptr
s也拥有它们所指向的对象。这意味着您无法从堆栈对象创建共享_ptr。要创建共享_ptr,请使用
new
make_shared

shared_ptr<Node> ptr1(new Node(42));
shared_ptr<Node> ptr2 = make_shared<Node>();
shared_ptr<Node> ptr3 = make_shared<Node>(99);

现在
ptr1
copy1
use_count()==2

有许多误解,但我将尝试解释: 在C++中,对象要么存储在<强>堆栈或<强>堆< /St>。在“强>堆栈>上创建的对象将被销毁,一旦离开声明的范围,它们的内存就会释放。
int bla()
{
    int a = 1;
    int b = 2;
    int result = a+b;
    return result;
}
在本例中,当程序进入函数
bla
时,3个
int
对象将被创建,当函数相应返回时,3个
int
对象将被销毁

然后就是。您可以通过
新建
在堆上创建对象。这些对象超出了创建它们的范围,但您必须记住通过
删除
销毁对象。因为这是一个常见的陷阱,也是内存漏洞的来源。标准库提供了助手类(例如,您已经找到的
shared_ptr
)来解决此问题。其思想是,
shared_ptr
对象将负责删除给定的对象(该对象必须在堆上(!)(是的,您可以通过自定义删除器绕过此操作,但这比此解释要高级一点))一旦共享的ptr本身被破坏。正如名字所暗示的那样,
共享的ptr
的意图是被共享。要被共享,你只需复制共享的ptr即可。
shared_ptr
实现有一个自定义的复制构造函数和复制赋值运算符,它将通过增加使用计数和复制当前处理的对象的地址来处理此问题。这是共享_ptr对象了解是否有其他实例管理同一对象的唯一方法t、 因此,要增加使用次数,您必须复制一份
共享\u ptr

现在让我解释一下哪里出了问题:

  • 初始的
    节点=节点(10);
    是在堆栈上创建的(与上面的int类似)。因此,无需手动管理生存期。您创建了一个
    共享\u ptr
    ,用于管理此节点的地址。这是一个错误。一旦您离开作用域,
    共享\u ptr
    和节点对象本身(通过堆栈上的自动操作)将删除节点对象。这很糟糕

  • 假设错误1不存在。因此我们有第二个错误: 您正在创建第二个,单独的
    共享\u ptr
    ,而不是从第一个复制。现在,两个现有的
    共享\u ptr
    彼此不了解,它们都将尝试删除节点对象。因此,我们再次进行了双重删除

  • 让我们假设您希望您的节点对象真正由
    共享\u ptr
    管理,您必须从一个共享\u ptr开始,然后从中复制您想要共享的内容。要创建第一个,您有两种可能:

    std::shared_ptr<int> mysharedpointer (new int(ANYNUMBER));
    auto mysharedpointer = std::make_shared<int>(ANYNUMBER);
    
    瞧,你有一个与共享所有权相关联的副本


    (这一切都有点简化,我肯定我错过了一些东西。请随意填写答案)

    (共享)&节点
    在多个级别上都是错误的。您可以通过说
    ptr2=ptr1;
    来增加使用计数,并且您不能获取局部变量的地址,因为它将在程序结束时尝试删除,并且会严重崩溃。除了@VTT的注释外,您还创建了两个不同的指针,它们是共享指针。而不是共享一个指针r、 顺便说一句,这个参考站点有(但是线程可能会让它更复杂一些)。虽然在创建
    ptr1
    ptr2
    时创建并传递了共享指针,但是这些都是临时的,会被销毁或移动。但是如果我想创建两个共享的\u ptr呢在同一个对象上?例如在代码中给定的节点对象上?@DeeJay Answer Revied.ptr2和ptr1是指向同一个节点对象的两个不同的共享\u ptr。我想你可能对代码在做什么有一些基本的困惑?@songyuanyao For ptr2,如果我这样做的话:共享\u ptrpr2(节点);这样做不好吗?@songyuanyao为什么ptr1和ptr2都指向同一地址时use_count()仍然是1?因此,如果我在堆上创建一个对象,我是否能够在其上创建共享的_ptr。
    例如
    Node Node=new Node(10);
    shared_ptr ptr1=make_shared(Node);
    shared_ptr ptr2=make_shared(Node)
    这是否会导致使用
    int bla()
    {
        int a = 1;
        int b = 2;
        int result = a+b;
        return result;
    }
    
    std::shared_ptr<int> mysharedpointer (new int(ANYNUMBER));
    auto mysharedpointer = std::make_shared<int>(ANYNUMBER);
    
    auto mysecondsharedpointer = mysharedpointer;