一、实验目的
●熟悉智能指针
●对智能指针进行设计和实现
二、实验实验环境: 在windows系统下用c++编写
三、实验内容
1. 对智能指针进行设计
2. 对智能指针进行实现
四、实验前的分析
由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。对于编译器来说,智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放有它管理的堆内存。所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。 访问智能指针包含的裸指针则可以用 get() 函数。由于智能指针是一个对象,所以if (my_smart_object)永远为真,要判断智能指针的裸指针是否为空,需要这样判断:if (my_smart_object.get())。智能指针包含了 reset() 方法,如果不传递参数(或者传递 NULL),则智能指针会释放当前管理的内存。如果传递一个对象,则智能指针会释放当前对象,来管理新传入的对象。 智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。它的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。 智能指针就是模拟指针动作的类。所有的智能指针都会重载 -> 和 * 操作符。智能指针还有许多其他功能,比较有用的是自动销毁。这主要是利用栈对象的有限作用域以及临时对象(有限作用域实现)析构函数释放内存。当然,智能指针还不止这些,还包括复制时可以修改源对象等。智能指针根据需求不同,设计也不同(写时复制,赋值即释放对象拥有权限、引用计数等,控制权转移等)。
五、实验步骤
1.建立一个名为smartpoint.cpp文件
2.定义仅由smartcount类使用的smartpoint类,用于封装使用计数和相关指针
- class smartpoint
- {
- int *ip;
- int P_use;
- smartpoint(int *p) : ip(p) , P_use(1)//初始化指针并将引用计数置为1
- {
- cout << "smartpoint constructor spoke !" << endl;
- }
- ~smartpoint()//定义析构函数
- {
- delete ip;
- cout << "smartpoint distructor spoke !" << endl;
- }
- friend class smartcount;// 将smartcount类设置为友元,使其成员可以访问smartpoint的成员
- };
定义smartcount类用于访问smartpoint类
- class smartcount
- {
- public:
- smartcount(int *p, int i) :st_conut (new smartpoint(p)) , val(i)// 构造函数:p是指向已经动态创建的int对象指针
- {
- cout << "smartcount constructor spoke ! " << "p_use = " <<st_conut->P_use << endl;
- }
- smartcount(const smartcount& orig) : st_conut(orig.st_conut) , val(orig.val)// 复制构造函数:复制成员并将使用计数加1
- {
- ++st_conut->P_use;
- cout << "smartcount copy constructor spoke ! " << "P_use = " << st_conut->P_use << endl;
- }
- smartcount& operator=(const smartcount&);// 赋值操作符
- ~smartcount()// 析构函数:如果计数为0,则删除smartpoint对象
- {
- cout << "smartcount distructor spoke ! " << "p_use = " << st_conut->P_use << endl;
- if (--st_conut->P_use == 0)
- delete st_conut;
- }
- private:
- smartpoint *st_conut; //指向使用计数类smartpoint
- int val;
- };
注:代码有参考网络资源
保存进行运行
六、实验小结及问题分析
(1)不管指针成员。复制时只复制指针,不复制指针指向的对象。当其中一个指针把其指向的对象的空间释放后,其它指针都成了悬浮指针。这是一种极端
(2)当复制的时候,即复制指针,也复制指针指向的对象。这样可能造成空间的浪费。因为指针指向的对象的复制不一定是必要的。
(3) 第三种就是一种折中的方式。利用一个辅助类来管理指针的复制。原来的类中有一个指针指向辅助类,辅助类的数据成员是一个计数器和一个指针(指向原来的)(此为本次智能指针实现方式)。
总之智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。