C++11笔记(2)

Smart Pointer智能指针

auto_ptr
在以前我们经常使用指针这个概念,指针既可以让我们精确的控制堆上的每一块内存,也让程序更加容易发生崩溃,这就让我们使用指针时必须要多加小心,所以在C++98开始便推出了auto_ptr,对裸指针进行封装,让程序员无需手动释放指针指向的内存区域,在auto_ptr生命周期结束时自动释放。

class A
{
public:
		A(){cout<<"A()"<<endl;}
		~A(){cout<<"~A()"<<endl;}
};
int main()
{
		auto_ptr<A>  pa(new A);
		return 0;
}

在指针pa生命周期结束时它会自动释放。
但是auto_ptr在转移指针所有权后会产生野指针,导致程序运行时崩溃。
auto_ptr p1(new int(10));
//转移控制权
auto_ptr p2=p1;

*p1+=10;//运行时崩溃,p1为空指针,可以用p1->get判空做保护。
因此在C++11又推出了unique_ptr、shared_ptr、weak_ptr三种智能指针,慢慢取代了auto_ptr.

unique_ptr
unique_ptr与auto_ptr一样对于同一块内存只能有一个持有者,但是unique_ptr不允许赋值操作,即不能放在等号的右边(函数的参数和返回值例外),这就会避免一些操作使指针所有权转移,但是unique_ptr踢空了专门的所有权转移的方法move ,使用move可以使原unique_ptr失效,但是这样再访问原unique_ptr时会发生崩溃。

unique_ptr<int> up(new int(5));
auto up2=up;//编译报错
auto up2=move(up);
cout<<*up<<endl;//运行时崩溃,因为控制权转移,up已经失效

shared_ptr
shared_ptr允许多个该智能指针共同指向同一个对象,他通过其中的计数器来实现,计数器会记录当前有多少个shared_ptr指向同一个对象,一旦最终到达其生命周期要被销毁时,当计数器变为0的时候才会销毁该对象,使用成员函数 use count()可以观察计数器的情况。

class A  
{  
public:  
    int i;  
    A(int n) :i(n) { cout << "A(int)" << endl; };  
    ~A() { cout << i << " " << "~A()" << endl; }  
};  
int main()  
{  
	    shared_ptr<A> sp1(new A(2));  //A(2)由sp1托管,  
	    shared_ptr<A> sp2(sp1);       //A(2)同时交由sp2托管  
	    shared_ptr<A> sp3;  
	    sp3 = sp2;   //A(2)同时交由sp3托管  
	    cout << sp1->i << "," << sp2->i << "," << sp3->i << endl;  
	    A * p = sp3.get();      // get返回托管的指针,p 指向 A(2)  
	    cout << p->i << endl;  //输出 2  
	    sp1.reset(new A(3));    // reset导致托管新的指针, 此时sp1托管A(3)  
	    sp2.reset(new A(4));    // sp2托管A(4)  
	    cout << sp1->i << endl; //输出 3  
	    sp3.reset(new A(5));    // sp3托管A(5),A(2)无人托管,被delete  
	    cout << "end" << endl;  
	    return 0;  
}  

weak ptr
weak ptr的出现是为了弥补shared ptr的缺陷,因为shared ptr有一个引用成环的问题
例:

class B;  
      
class A  
{  
public:  
    A(){ cout << "A()" << endl; };  
    ~A() { cout << "~A()" << endl; }  
    shared_ptr<B> pb;  
};  
	  
class B  
{  
public:  
    B() { cout << "B()" << endl; };  
    ~B() { cout << "~B()" << endl; }  
    shared_ptr<A> pa;  
};  
  
int main()  
{  
    shared_ptr<A> PA(new A);  
    shared_ptr<B> PB(new B);  
  
    PA->pb = PB;  
    PB->pa = PA;  
      
    return 0;//A和B没有析构。  
}  

这就是引用成环的问题。
而解决这种问题我们只需要将两个类中的一个成员变量改为weak ptr对象,而weak ptr不会增加计数器的值,所以不会造成引用成环的现象。

class B;  
      
class A  
{  
public:  
    A(){ cout << "A()" << endl; };  
    ~A() { cout << "~A()" << endl; }  
   weak_ptr<B> pb;  
};  
	  
class B  
{  
public:  
    B() { cout << "B()" << endl; };  
    ~B() { cout << "~B()" << endl; }  
    shared_ptr<A> pa;  
};  
  
int main()  
{  
    shared_ptr<A> PA(new A);  
    shared_ptr<B> PB(new B);  
  
    PA->pb = PB;  
    PB->pa = PA;  
      
    return 0;//A和B都得以析构。  
}  

Lambda函数
它可以定义一个临时的函数对象,可以像其他对象一样可以传递和保存,并且最强大的是它可以访问当前函数上下文。

例:

auto add=[ ](int a,int b){return a+b;}
std::cout<<add(1,2)<<std::endl;

=后面的部分就是lambda函数,先忽略前面的[]。()里面的是参数列表,{}里面的是实现.跟普通函数基本一样。
但是这里没有返回值类型,所以系统会根据return语句进行推导,如果有多个return语句,并且类型不一样的话就会报错。
使用的方式与普通函数一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值