C++中智能指针的简单使用
在C++中的类中,一定会有4大函数。构造函数,拷贝构造函数,赋值重载运算符,析构函数。如果在类的声明中,我们没有显示的定义,那么编译器将会自动为我们完成。那么各个函数的作用是什么?为什么编译器会给我们合成呢?那就是说,在类的编译过程中,或者说在对象的创建过程中,以上四个函数都必须存在。首先分析下他们各自的作用。
构造函数(constructor):完全是为了构造对象而存在。对数据成员进行初始化。手段就是利用初始化成员列表或者在构造函数体内完成。本质 初始化的目的。
拷贝构造函数(copy constructor): 本质是为用已经存在的对象来构造待存在的对象。该对象此时还未存在。
赋值重载运算符( copy assigment operator):本质是对已经存在的对象进行刷新。比如 a=b。a,b都存在,只是a刷新为b.
析构函数(destructor):在对象的销毁时候,调用该函数。本质是为了回收内存。
那么对于没有显示的使用拷贝构造和赋值重载运算符。进行的就是所谓的“浅拷贝”。即是完全的值拷贝。突出的不同就在于指针变量的问题。对于类中出现指针变量时候,进行浅拷贝的话,那么两个类的指针变量都只向同一块内存,那么在析构的时候,就会出现一块内存析构两次,出现内存泄露情况。
如何能阻止这种情况呢?这就是拷贝构造函数的功能了。也就是说我们自己完全接管复制拷贝的过程,而不要编译器为我们干。
智能指针的使用。虽然使用上稍微复杂些,但是节省内存。
智能指针的思路:使用一个专门的类来管理内存。也就是说改类内部维护一个计数器,各个类中的指针都指向同一块内存,但是只有在计数器类内使用次数为0的情况下,才去销毁内存。这样就不会造成一块内存被销毁两次了。
下面见代码:
// 智能指针的简单使用 #include <iostream> using namespace std; class SmartPoint { private: SmartPoint(int *p):ptr(p),usecnt(1){}; //构造函数 ~SmartPoint(){delete ptr;}; //销毁 friend class Sample; //该智能指针 用友元类来访问 size_t usecnt; //使用次数 int *ptr; //指向的指针 }; class Sample { public: Sample(int *p):smptr(new SmartPoint(p)){}; //构造函数 Sample(const Sample &obj):smptr(obj.smptr){ ++smptr->usecnt;} //拷贝构造函数 维护指针 ~Sample() //析构函数 { if(--smptr->usecnt==0) delete smptr; } int getval(){return *(smptr->ptr);} private: SmartPoint *smptr; }; int main() { int *p=new int(10); Sample *pa=new Sample(p); //用p来创建a对象 cout<<"a.smptr="<<pa->getval()<<endl; Sample *pb=new Sample((*pa)); cout<<"b.smptr="<<pb->getval()<<endl; delete pa; delete pb; return 0; }
说明:上述代码中使用SmartPoint类来维护一个计数器usecnt和一个指针。当进行复制时候,该计数器加1,那么当该计数器usecnt==0时候,则delete p;这个时候会自动去调用SmartPoint的析构函数,进行删除内存。
使用计数器的思想在windows OS很多见。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。