【问题标题】:Why dereferencing a unique_ptr won't modify the original object为什么取消引用 unique_ptr 不会修改原始对象
【发布时间】:2016-09-14 08:29:23
【问题描述】:

看下面的例子,我使用了一个唯一指针和一个指向a的原始指针,我的问题是,为什么原始指针可以工作,而唯一指针却不行?如果我想使用unique_ptr 或shared_ptr 将字符串a 修改为引用,我该怎么办?

示例程序:

#include <iostream>
#include <string>
#include <memory>

int main()
{
    using namespace std;
    string a = "aaa";
    auto ptr = std::make_unique<string>(a);
    auto ptr2 = &a;
    cout << "before, a: " << a << endl;
    *ptr += "bbb";
    cout << "After, a: " << a << endl;
    *ptr2 += "ccc";
    cout << "after 2, a: " << a << endl;
}

输出:

before, a: aaa
After, a: aaa
after 2, a: aaaccc

【问题讨论】:

    标签: c++ pointers smart-pointers


    【解决方案1】:

    std::make_unique&lt;string&gt;(a); 将new 一个全新的std::string (从a 初始化),稍后由ptr 指向。所以对象被*ptr += "bbb"修改了,但和原来的对象a无关。

    您可以通过以下演示确认unique_ptr所指向的对象已修改:

    string* pa = new string("aaa");
    unique_ptr<string> ptr(pa);
    auto ptr2 = pa;
    cout << "before, *pa: " << *pa << endl;
    *ptr += "bbb";
    cout << "After, *pa: " << *pa << endl;
    *ptr2 += "ccc";
    cout << "after 2, *pa: " << *pa << endl;
    

    结果:

    before, *pa: aaa
    After, *pa: aaabbb
    after 2, *pa: aaabbbccc
    

    LIVE

    【讨论】:

      【解决方案2】:

      std::unique_ptr 必须引用一个动态分配的对象(以便它可以安全地最终删除它)。这就是std::make_unique 创建一个新对象的原因。

      这将work up to your expectations:

      #include <iostream>
      #include <string>
      #include <memory>
      
      int main()
      {
          using namespace std;
          string* a = new string("aaa");
          std::unique_ptr<string> ptr(a);
          auto ptr2 = a;
          cout << "before, a: " << *a << endl;
          *ptr += "bbb";
          cout << "After, a: " << *a << endl;
          *ptr2 += "ccc";
          cout << "after 2, a: " << *a << endl;
      }
      

      输出:

      before, a: aaa
      After, a: aaabbb
      after 2, a: aaabbbccc
      

      【讨论】:

        【解决方案3】:

        因为std::make_unique&lt;string&gt;(a) 创建了一个全新的std::string 对象并使用a 的内容对其进行初始化。新字符串和旧的a 没有任何联系。

        【讨论】:

          【解决方案4】:

          Make unique 构造一个 T 类型的对象并将其包装在一个 unique_ptr 中。您实际上可能在不注意的情况下复制了“a”。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-10-21
            • 1970-01-01
            • 1970-01-01
            • 2017-09-11
            • 2019-07-27
            • 1970-01-01
            • 1970-01-01
            • 2013-11-13
            相关资源
            最近更新 更多