为什么取消引用 unique_ptr 不会修改原始对象
Why dereferencing a unique_ptr won't modify the original object
看下面的例子,我使用了一个唯一指针和一个原始指针指向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
因为std::make_unique<string>(a)
创建了一个全新的std::string
对象并用a
的内容初始化了它。新字符串和旧字符串a
没有任何联系。
std::make_unique<string>(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
Make unique 构造一个 T 类型的对象并将其包装在 unique_ptr 中。您可能实际上正在复制 "a" 而您没有注意到它。
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
看下面的例子,我使用了一个唯一指针和一个原始指针指向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
因为std::make_unique<string>(a)
创建了一个全新的std::string
对象并用a
的内容初始化了它。新字符串和旧字符串a
没有任何联系。
std::make_unique<string>(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
Make unique 构造一个 T 类型的对象并将其包装在 unique_ptr 中。您可能实际上正在复制 "a" 而您没有注意到它。
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