• C++ STL Smart Pointer 智能指针(二)unique_ptr


      unique_ptr实现了独占式拥有概念,它可以保证一个对象和其相应的资源同一时间只被一个pointer拥有。一旦拥有者被销毁或变成empty,或开始拥有另一个对象,先前拥有的那个对象就会被销毁,其任何相应的资源亦会被释放。

    1.使用unique_ptr

    #include <iostream>
    #include <string>
    #include <memory>
    using namespace std;
    int main(){
        unique_ptr<string> up(new string("nico"));
        (*up)[0]='N';
        up->append("lai");
        cout<<*up<<endl;
    }

    输出:

    Nicolai

    2.转移unique_ptr的拥有权

    以下的代码是错误的:

    std::string* sp=new std::string("hello");
    std::unique_ptr<std::string> up1(sp);
    std::unique_ptr<std::string> up2(sp);

    up1和up2拥有了同样的对象。

    unique_ptr<A> up1(new A("a1"));
    unique_ptr<A> up2(up1); //Error:up1 and up2 own same data

    这里的up2不可以成为原对象的另一个拥有者。

    正确的转移方法:

    unique_ptr<A> up1(new A("a1"));
    unique_ptr<A> up2(move(up1));
    unique_ptr<A> up3;
    up3=move(up2);

    3.被当作成员

     a.h

    #ifndef A_H
    #define A_H
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class A
    {
    public:
        A(string n);
        A(int n);
        ~A();
        int a=0;
        string s="a";
    };
    
    #endif // A_H

    a.cpp

    #include "a.h"
    
    A::A(string n)
    {
        s=n;
    }
    
    A::A(int n){
        a=n;
    }
    
    A::~A(){
        cout<<"delete "<<s<<endl;
    }

    b.h

    #ifndef B_H
    #define B_H
    #include <iostream>
    #include "a.h"
    #include <string>
    #include <memory>
    
    using namespace std;
    
    class B
    {
    public:
        B(int val1,int val2);
        B(const B& x);
        B& operator =(const B& x);
        void print();
    private:
        unique_ptr<A> ptr1;
        unique_ptr<A> ptr2;
    };
    
    #endif // B_H

    b.cpp

    #include "b.h"
    
    B::B(int val1,int val2):ptr1(new A(val1)),ptr2(new A(val2))
    {
    
    }
    B::B(const B &x):ptr1(new A(*x.ptr1)),ptr2(new A(*x.ptr2)){
    
    }
    B& B::operator =(const B& x){
        *ptr1=*x.ptr1;
        *ptr2=*x.ptr2;
        return *this;
    }
    void B::print(){
        cout<<"p1: "<<ptr1->a<<" p2: "<<ptr2->a<<endl;
    }

    main函数

    int main(){
        B b(10,1);
        b.print();
    }

    输出:

    p1: 10 p2: 1
    delete a
    delete a

      对于B,你可以不写析构函数,因为unique_ptr会为你做了该做的事。你还必须写出copy构造函数和赋值操作符;此二者的默认版本会拷贝复制成员,而在此那是不可能的。如果你没有自行提供它们,Class B将只能提供move语义。

    4.对付Array

      基于C语言以来的规定,C++无法区分指针是“指向单对象”还是“指向array”。C++规定,对于数组应该使用delete[]而不是delete。所以以下语句是错误的:

    std::unique_ptr<std::string> up(new std::string[10]);

      C++标准库为unique_ptr提供了一个偏特化的版本用来处理array,这个版本会在遗失其所指对象的拥有权时,对该对象调用delete[]。使用方法如下:

    int main(){
        unique_ptr<string[]> up6(new string[10]);
        up6[0]="aaa";
        //cout<<*up<<endl;//Error
        cout<<"up6[0]:"<<up6[0]<<endl;
    }

      然而,这个版本的接口稍有不同。它不再提供操作符*和->,而改提供操作符[]。

      这个class不接受派生类型的array作为初值,因此起不到多态的作用。

  • 相关阅读:
    hibernate 4 需要导入的jar包
    中国象棋马走日(要求打印每一种走法) — 递归
    最长公共子串
    国际象棋马走日(骑士周游)
    八皇后
    约瑟夫问题
    hashtable的运用实例
    用较小的代价去除字符串中的空格
    C++ string数据类型的实现
    strcpy、strncpy与memcpy的区别与使用方法
  • 原文地址:https://www.cnblogs.com/xiaoaofengyue/p/13138417.html
Copyright © 2020-2023  润新知