一、auto_ptr 特点

  1. 支持拷贝构造
  2. 支持赋值拷贝
  3. 支持 operator->/operator* 解引用
  4. 支持指针变量重置
  5. 保证指针持有者唯一(涉及所有权转移)

二、问题一:使用数组存储 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_ptrstd::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 变量已失效