本笔记主要用于帮助楼主复习,参考价值低。。。。
1、智能指针--auto_ptr与shared_ptr
智能指针类型挺多的,如std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::weak_ptr、boost:: intrusive_ptr,这里只说其中二种。
智能指针用于内存管理,主要是用于对堆上面开辟的内存的管理(栈上的内存由编译器负责分配和释放),具体采用引用计数的机制进行。
智能指针的最基本的概念是引用计数,也就是智能指针内部有一个计数器,记录了当前内存资源到底有多少指针在访问这个资源,当新增加一个可以访问这个资源的引用时,计数器会加1,反之会减去1,当计数器为0时,智能指针会自动释放他所管理的资源。手动申请,自动释放,就是其智能的体现。
比如我们在堆上开辟了一块内存m1,并将其赋值给指针p1,那么现在m1这块内存就有一个对象在使用,引用计数为1。这时如果有另外一个指针p2也需要使用m1的内容,那么就将p2也指向m1。问题在于,如果p1使用完毕之后,使用delete语句告诉系统,这块内存我不用了,把它回收吧,那么这时p2还在指着m1的话,再次使用p2的时候就会出问题了。
然后就引入了引用计数的概念。所有的栈上的内存,在还没有被开辟的时候,该块内存的引用计数为0,在第一次用p1开辟的时候引用计数+1变成1,如果有其他指针也需要这块内存,比如一个潜copy操作,比如p2,那么这时候就有两个指针指向m1,引用计数变成2,当p1用完了,就用一个操作切断p1和m1的关系,m1的引用计数变成1。当p2也用完了,那么通过一个操作引用计数再次减去1,引用计数变成0。当智能指针这个对象发现它管理的内存引用计数变成0的时候,对m1做一个delete操作,使之释放。
智能指针和普通指针的区别在于智能指针实际上是对普通指针加了一层封装机制,这样的一层封装机制的目的是为了使得智能指针可以方便的管理一个对象的生命期。
在C++中,我们知道,如果使用普通指针来创建一个指向某个对象的指针,那么在使用完这个对象之后我们需要自己删除它,例如:
ObjectType* temp_ptr = new ObjectType();
temp_ptr->foo();
delete temp_ptr;
很多材料上都会指出说如果程序员忘记在调用完temp_ptr之后删除temp_ptr,那么会造成一个悬挂指针(dangling pointer),也就是说这个指针现在指向的内存区域其内容程序员无法把握和控制,也可能非常容易造成内存泄漏。
可是事实上,不止是“忘记”,在上述的这一段程序中,如果foo()在运行时抛出异常,那么temp_ptr所指向的对象仍然不会被安全删除。
扯了这么多,总算把概念说清楚了。
std::auto_ptr
是当前C++标准库中提供的一种智能指针,其在构造时获取某个对象的所有权(ownership),主要为了解决“被异常抛出时发生资源泄露”的问题。
auto_ptr使用注意事项:
(1)auto_ptr不能共享所有权
int * p=new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);
因为ap1和ap2都认为指针p是归他管的,在析构时都试图删除p,这是不允许的。
(2)auto_ptr不能指向数组
int * pa=new int[10];
auto_ptr<int> ap(pa);
因为auto_ptr的析构函数中删除指针用的是delete,而不是delete[],所以不应该用auto_ptr来管理一个数组指针。
(3)auto_ptr不能作为容器的成员
与引用计数型智能指针不同,auto_ptr要求其对“裸”指针的完全占有性,在拷贝赋值操作是,auto_ptr的做法是“所有权转移”,给别人东西而自己不再持有。
不符合STL标准容器的要求。
int* p=new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2=ap1;
cout<<*ap1; //error,此时ap1只剩下一个NULL指针在手了
(4)不要把auto_ptr放入容器
(5)不能通过赋值操作来初始化auto_ptr
std::auto_ptr<int> p(new int(42)); //OK
std::auto_ptr<int> p = new int(42); //ERROR
boost::shared_ptr
shared_ptr是boost库中的引用计数智能指针(上述介绍了很多了),解决了在多个指针间共享对象所有权的问题,同时也满足容器对元素的要求,因而可以安全地放入容器中。其在非环形数据结构总防止资源泄露很有帮助。
代码实现(晚上回去贴)
//今天一个上午都在帮mentor整理专利,好多东西都没看,呜呜~~~~
2、指针与const
这个我老是会出错,即使现在理解了,以后用到的时候还是出错,好记性不如烂笔头。
常量指针(指针可变,指向的内容不可变)
const double *a;
double const *a;
指针常量(指针不能变,指向的内容可变)
double * const a;
double * a const;