一、auto_ptr 特点
- 支持拷贝构造
- 支持赋值拷贝
- 支持
operator->/operator*
解引用 - 支持指针变量重置
- 保证指针持有者唯一(涉及所有权转移)
二、问题一:使用数组存储 auto_ptr
std::vector<std::auto_ptr<People>> peoples;
// 这里实例化多个people并保存到数组中
...
std::auto_ptr<People> one = peoples[5];
...
std::cout << peoples[5]->get_name() << std::endl;
原因在于 std::auto_ptr
支持 operator=
,为了确保指针所有者唯一,这里转移了所有权,people[5] 变成了 null
三、问题二、函数传参 auto_ptr 类型
void do_somthing(std::auto_ptr<People> people){
// 该函数内不对people变量执行各种隐式/显示的所有权转移和释放
...
}
std::auto_ptr<People> people(new People("jony"));
do_something(people);
...
std::cout << people->get_name() << std::endl;
原因在于 std::auto_ptr支持拷贝构造
,为了确保指针所有者唯一,这里转移了所有权
四、unique_ptr
在11中,可以支持右值以及移动语义了,此时可以完全匹配auto_ptr的所有权管理,新增了 std::unique_ptr
。std::unique_ptr
不仅加入了移动语义的支持,同时也关闭了左值拷贝构造和左值赋值功能!杜绝了上述场景的出现!但是,此时,需要使用其他的方案了。比如场景一中,std::unique_ptr类型变量不能使用vector保存了!
所以 std::auto_ptr
废弃了,由 std::unique_ptr
代替!
class Person{
public:
int getAge()const{
return m_age;
}
void setAge(int age){
m_age = age;
}
private:
int m_age{20};
};
unique_ptr<Person> Change(unique_ptr<Person> p){
p->setAge(30);
return p;
}
int main()
{
unique_ptr<Person> pP(new Person);
cout << pP->getAge() << endl;
// unique_ptr<Person> pP2 = Change(pP); // error: unique_ptr 删除了拷贝构造,所以需要使用 move 关键字转移所有权
unique_ptr<Person> pP2 = Change(move(pP));
// pP = pP2; // error:unique_ptr 删除了 = 赋值构造
cout << "-------------" << endl;
cout << pP2->getAge() << endl;
cout << "-------------" << endl;
if(pP == nullptr){
cout << "pP 变量已失效" << endl;
}
return 0;
}
输出:
20
-------------
30
-------------
pP 变量已失效