简体   繁体   中英

Why dereferencing a unique_ptr won't modify the original object

See the following example, I've used a unique pointer and a raw pointer to a , my question is, why does the raw pointer work but not the unique pointer? If I want to modify string a like a reference by using the unique_ptr or shared_ptr , what should I do?

Example program:

#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;
}

Output:

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

std::make_unique<string>(a); will new a brand new std::string (initialized from a ), which is pointed by ptr later. So the object is modified by *ptr += "bbb" , but it has nothing to do with the original object a .

You could confirm that the object pointed by unique_ptr is modified, via the following demo:

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;

Result:

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

LIVE

std::unique_ptr must refer to a dynamically allocated object (so that it can safely delete it in the end). That's why std::make_unique creates a new object.

This will 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;
}

Output:

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

Because std::make_unique<string>(a) creates a completely new std::string object and initializes it with the contents of a . The new string and the old a have no connection with each other.

Make unique constructs an object of the type T and wraps it in a unique_ptr. You may be actually making a copy of "a" without you noticing it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM