C++智能指针测试
2016-04-13 10:40
281 查看
<pre class="cpp" name="code"><pre class="cpp" name="code">#include <iostream> #include <memory> #include <assert.h> using namespace std; int main(int argc, char* argv[]) { int *p1 = new int(10); int *p2 = new int(10); p2 = p1; std::shared_ptr<int> sp(new int(10));//一个指向整数的shared_ptr // std::shared_ptr<int> sp(p1); // std::shared_ptr<int> sp = make_shared<int>(10); // assert(sp.unique());//现在shared_ptr 是指针的唯一持有者 std::shared_ptr<int> sp2(p2);//第二个shared_ptr ,拷贝构造函数 // std::shared_ptr<int> sp2(p1);//第二个shared_ptr ,拷贝构造函数 // std::shared_ptr<int> sp2(sp.get()); std::shared_ptr<int> sp3(sp2); //两个shared_ptr 相等,指向同一个对象,且引用计数为2 std::cout << sp.use_count() << std::endl; std::cout << sp2.use_count() << std::endl; std::cout << sp.unique() << std::endl; std::cout << (sp == sp2) << std::endl; std::cout << (*sp == *sp2) << std::endl; *sp2 = 50; std::cout << *sp << std::endl; //assert(sp == sp2 );//&& sp.use_count() == 1 && sp2.use_count() == 1 *sp2 = 100;//使用解引用操作符修改被指对象 assert(*sp2 == 100);//另一个shared_ptr 同时也被修改 sp.reset(); assert(!sp);//sp 不再持有对象 return 0; }
经测试可以看出,一个普通的指针p1只能初始化一个智能指针shared_ptr sp,如果还想要一个智能指针sp2指向p1,必须一定要用sp来初始化sp2。
如果也用p1初始化sp2,则sp与sp2的引用计数都只有1,而且可以测试出引用计数是不唯一的。不过sp==sp2竟然值为1。
测试完毕后可以大致判断出智能指针的运行机制如下。
一个智能指针若是使用普通指针进行初始化,则会创建一个控制器,控制器里会记录该普通指针(即指向的内存位置)和引用计数,引用计数置为1
若同一个普通指针(也可以是指向同样内存的2个普通指针)对2个智能指针进行初始化。 则会创建2个控制器,2个控制器会是独立的,引用计数均为1。而且后面会出现重复析构,所以需避免该用法。
sp.unique()的判断依据应该是引用计数是否为1。
而且这2个智能指针竟然sp==sp2,也就是说相等符号的判断依据应该是 判断控制器里的普通指针(即指向的内存位置)是否相同, 而不是判断控制器是否相等,也不是判断引用计数是否相等。 // 这里也可以看出,智能指针尽量模仿指针的用法,想想这样做还是很合理的。
同样,判断2个智能指针的值是否相等*sp==*sp2, 类似普通指针,判断依据 只考虑值是否相等, (即使指向的内存位置不同,但只要值相等即可,就判断相等)。
上面是通过测试来估计运行机制,来更深刻的记住智能指针的方法,这样对于一些不规范的代码进行分析,当然不规范就要改成规范。
总而言之,以后使用智能指针,应避免出现普通指针,也就是是说应按照如下规范
// Use make_shared function when possible.
auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");
// Ok, but slightly less efficient.
// Note: Using new expression as constructor argument
// creates no named variable for other code to access.
shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance")); //尽量少用这个方法,这样也更加美观,效率也不错
// When initialization must be separate from declaration, e.g. class members,
// initialize with nullptr to make your programming intent explicit.
shared_ptr<Song> sp5(nullptr);
//Equivalent to: shared_ptr<Song> sp5;
//...
sp5 = make_shared<Song>(L"Elton John", L"I'm Still Standing");
//Initialize with copy constructor. Increments ref count.
auto sp3(sp2);
//Initialize via assignment. Increments ref count.
auto sp4 = sp2;
//Initialize with nullptr. sp7 is empty.
shared_ptr<Song> sp7(nullptr);
学习笔记:shared_ptr陷阱
http://blog.csdn.net/liuzhi1218/article/details/6993554 https://msdn.microsoft.com/zh-cn/library/hh279674.aspx http://mingxinglai.com/cn/2013/01/smart-ptr/
相关文章推荐
- C/c++程序内存分配
- 研究C语言的参数执行顺序
- C++中函数指针与数组
- C++ vector用法
- C语言的文件读取与写入操作
- C语言学习笔记(1)
- C语言-(单-双)链表
- C语言中全局变量、局部变量、静态全局变量、静态局部变量的区别
- C语言(一个真实的故事)
- C/C++中extern关键字详解
- C++学习笔记--第一章 C++概述
- C/C++中字符函数库ctype.h
- 【C++】菱形继承与虚拟菱形继承的对比分析
- Static Members:
- 《C++primer》读书笔记一
- 地球坐标,火星坐标,百度坐标转换C++
- c++实现md5加密
- C++资源汇总
- C++ string类:find()和find_first_of()
- 现代C++