拷贝控制
前文我们介绍了HasPtr类的拷贝控制,实现了行为像值的类,所谓行为像值的类就是我们所说的深拷贝,将一个类对象拷贝给另一个类对象时,其所有的成员都作为副本在新的类对象创建一遍,如果是指针类型的成员,则将指针指向的空间的数据复制一份给新对象,这样两个对象所有的成员都不关联,实现了深拷贝,不会受彼此影响。比如之前的HasPtr的拷贝构造
1 | HasPtr::HasPtr(const HasPtr &hp) |
下面我们介绍另一只拷贝控制,行为类似于指针的类,所谓行为类似于指针的类就是在类对象进行拷贝构造时,如果有指针成员,则浅拷贝,将指针的值赋值给新的对象,这两个对象共享同一个指针成员的指针。
我们同样实现另一个类SharePtr类,其内部有一个指针成员ps,现在我们实现这样的需求,多个SharePtr之间拷贝构造或者赋值,将ps做浅拷贝,也就是直接赋值给新对象,当所有SharePtr对象销毁后,才销毁成员ps。简单来讲,SharePtr的声明如下
1 | class SharePtr |
usecount用来管理引用计数,表示多少个SharePtr类对象共享字符串指针。
pstr字符串指针,在SharePtr对象拷贝构造和赋值等操作时,将pstr赋值给新对象,实现浅拷贝。
接下来我们实现拷贝构造和拷贝赋值
1 | SharePtr &SharePtr::operator=(const SharePtr &sptr) |
实现了拷贝构造和拷贝赋值,首先都要判断是否是自拷贝或者自赋值,如果不是自拷贝,那就将对方的引用计数增加1并且赋值给自己。对于赋值运算,先将自己原来指向的引用计数-1,如果引用计数为0则回收原来开辟的内存。然后将被拷贝的对象引用计数+1,然后赋值给自己。
对于析构函数,先减少引用计数,如果引用计数为0则回收内存
1 | SharePtr::~SharePtr() |
接下来我们实现一个打印引用计数的函数,一个测试函数
1 | //获取引用计数 |
在主函数中调用test_share结果输出如下
1 | sptr1 use count is 2 |
因为我们只开辟了两份对象,sptr1和sptr3,所以最后会回收两个对象。sptr2是拷贝构造生成的,共享了sptr1的数据。
可以看到拷贝赋值减少了=左边的引用计数,增加了=右边的引用计数。拷贝构造增加了引用计数,两个对象都共享一套数据。
总结
这个例子实现了类指针行为的类SharePtr,其行为很像智能指针,只不过智能指针通过模板实现了泛型而已。所以通过这个例子我们可以理解智能指针的工作原理和内部实现了。
源码链接
https://gitee.com/secondtonone1/cpplearn
想系统学习更多C++知识,可点击下方链接。
C++基础