关于 unique_ptr 所有权转让的问题
Questions about the ownership transfer of unique_ptr
对于以下代码:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct pm
{
pm() : a(make_unique<vector<int>>(1, 10)){};
unique_ptr<vector<int>> a;
};
struct parms
{
parms() : a(make_unique<pm>()){};
unique_ptr<pm> a;
};
class test
{
public:
test() : p(make_unique<parms>()) {}
unique_ptr<const parms> getParms()
{
return move(p);
}
void setParms(int b)
{
p->a->a->push_back(b);
}
void pp()
{
cout << p->a->a->at(0) << "\n";
}
private:
unique_ptr<parms> p;
};
int main()
{
auto t = make_unique<test>();
t->pp();
cout << t->getParms()->a->a->at(0) << "\n";
cout << (t->getParms()==nullptr) << "\n"; ;
}
t->getParms() 在我们 "cout << t->getParms()->a->a->at(0) << "\n"; 之后是一个 nullptr。
如果我们对 ptr 做同样的事情,
int main()
{
auto t = make_unique<test>();
t->setParms(5);
t->pp();
auto ptr = t->getParms();
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
}
ptr 不是 nullptr。
我的问题是:为什么 cout t->getParms(),然后 t->getParms() 是 nullptr 而 prt 不是?是因为unique_ptr的life scope吗?还是临时右值?这种行为背后的原因是什么?
您的方法 getParams()
将所有权转移给调用者。
unique_ptr<const parms> getParms()
{
return move(p);
}
成员移动到 return 值,现在调用者拥有指针对象。您没有在此处存储 returned 值:
cout << t->getParms()->a->a->at(0) << "\n";
尽管如此,即使您这样做了,t
也不再拥有 param
,因此当您再次询问 t
时:
cout << (t->getParms()==nullptr) << "\n"; ;
它不知道 param
了。
在第二个示例中,您将所有权从 t
转移到 ptr
:
auto ptr = t->getParms();
现在 ptr
拥有 param
。您可以随时检查指针或值:
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
这两条线没有所有权转移。
What's the reason behind this behavior?
如上所述,原因是 getParams()
将所有权转移给调用者。这对于 getter 方法来说相当不常见。也许“stealer-method”会是一个更好的名字;)。如果你不想放弃所有权(并且你确定指针是有效的)你可以简单地 return 一个参考:
const parms& getParms() const { return *p; }
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not?
t->getParms()
将所有权转移给调用者。这会将 t->p
设置为空。由于 t->p
不再拥有指针,所以当您第二次调用 t->getParms()
时,没有任何东西可以传递。
您从未从 ptr
转让所有权,因此它尚未设置为空。
对于以下代码:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct pm
{
pm() : a(make_unique<vector<int>>(1, 10)){};
unique_ptr<vector<int>> a;
};
struct parms
{
parms() : a(make_unique<pm>()){};
unique_ptr<pm> a;
};
class test
{
public:
test() : p(make_unique<parms>()) {}
unique_ptr<const parms> getParms()
{
return move(p);
}
void setParms(int b)
{
p->a->a->push_back(b);
}
void pp()
{
cout << p->a->a->at(0) << "\n";
}
private:
unique_ptr<parms> p;
};
int main()
{
auto t = make_unique<test>();
t->pp();
cout << t->getParms()->a->a->at(0) << "\n";
cout << (t->getParms()==nullptr) << "\n"; ;
}
t->getParms() 在我们 "cout << t->getParms()->a->a->at(0) << "\n"; 之后是一个 nullptr。
如果我们对 ptr 做同样的事情,
int main()
{
auto t = make_unique<test>();
t->setParms(5);
t->pp();
auto ptr = t->getParms();
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
}
ptr 不是 nullptr。
我的问题是:为什么 cout t->getParms(),然后 t->getParms() 是 nullptr 而 prt 不是?是因为unique_ptr的life scope吗?还是临时右值?这种行为背后的原因是什么?
您的方法 getParams()
将所有权转移给调用者。
unique_ptr<const parms> getParms()
{
return move(p);
}
成员移动到 return 值,现在调用者拥有指针对象。您没有在此处存储 returned 值:
cout << t->getParms()->a->a->at(0) << "\n";
尽管如此,即使您这样做了,t
也不再拥有 param
,因此当您再次询问 t
时:
cout << (t->getParms()==nullptr) << "\n"; ;
它不知道 param
了。
在第二个示例中,您将所有权从 t
转移到 ptr
:
auto ptr = t->getParms();
现在 ptr
拥有 param
。您可以随时检查指针或值:
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
这两条线没有所有权转移。
What's the reason behind this behavior?
如上所述,原因是 getParams()
将所有权转移给调用者。这对于 getter 方法来说相当不常见。也许“stealer-method”会是一个更好的名字;)。如果你不想放弃所有权(并且你确定指针是有效的)你可以简单地 return 一个参考:
const parms& getParms() const { return *p; }
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not?
t->getParms()
将所有权转移给调用者。这会将 t->p
设置为空。由于 t->p
不再拥有指针,所以当您第二次调用 t->getParms()
时,没有任何东西可以传递。
您从未从 ptr
转让所有权,因此它尚未设置为空。