最近看代码,智能指针用的比较多,自己平时用的少,周末自己总结总结。方便后续使用。
std::shared_ptr大概总结有以下几点:
(1) 智能指针主要的用途就是方便资源的管理,自动释放没有指针引用的资源。
(2) 使用引用计数来标识是否有多余指针指向该资源。(注意,shart_ptr本身指针会占1个引用)
(3) 在赋值操作中, 原来资源的引用计数会减一,新指向的资源引用计数会加一。
std::shared_ptr<Test> p1(new Test);
std::shared_ptr<Test> p2(new Test);
p1 = p2;
(4) 引用计数加一/减一操作是原子性的,所以线程安全的。
(5) make_shared要优于使用new,make_shared可以一次将需要内存分配好。
std::shared_ptr<Test> p = std::make_shared<Test>();
std::shared_ptr<Test> p(new Test);
(6) std::shared_ptr的大小是原始指针的两倍,因为它的内部有一个原始指针指向资源,同时有个指针指向引用计数。
(7) 引用计数是分配在动态分配的,std::shared_ptr支持拷贝,新的指针获可以获取前引用计数个数。
下面是一段示例代码,注释详细:
1 include <iostream> 2 #include <memory> 3 #include <thread> 4 #include <chrono> 5 #include <mutex> 6 7 struct Test 8 { 9 Test() { std::cout << " Test::Test()\n"; } 10 ~Test() { std::cout << " Test::~Test()\n"; } 11 }; 12 13 //线程函数 14 void thr(std::shared_ptr<Test> p) 15 { 16 //线程暂停1s 17 std::this_thread::sleep_for(std::chrono::seconds(1)); 18 19 //赋值操作, shared_ptr引用计数use_cont加1(c++11中是原子操作) 20 std::shared_ptr<Test> lp = p; 21 { 22 //static变量(单例模式),多线程同步用 23 static std::mutex io_mutex; 24 25 //std::lock_guard加锁 26 std::lock_guard<std::mutex> lk(io_mutex); 27 std::cout << "local pointer in a thread:\n" 28 << " lp.get() = " << lp.get() 29 << ", lp.use_count() = " << lp.use_count() << '\n'; 30 } 31 } 32 33 int main() 34 { 35 //使用make_shared一次分配好需要内存 36 std::shared_ptr<Test> p = std::make_shared<Test>(); 37 //std::shared_ptr<Test> p(new Test); 38 39 std::cout << "Created a shared Test\n" 40 << " p.get() = " << p.get() 41 << ", p.use_count() = " << p.use_count() << '\n'; 42 43 //创建三个线程,t1,t2,t3 44 //形参作为拷贝, 引用计数也会加1 45 std::thread t1(thr, p), t2(thr, p), t3(thr, p); 46 std::cout << "Shared ownership between 3 threads and released\n" 47 << "ownership from main:\n" 48 << " p.get() = " << p.get() 49 << ", p.use_count() = " << p.use_count() << '\n'; 50 //等待结束 51 t1.join(); t2.join(); t3.join(); 52 std::cout << "All threads completed, the last one deleted\n"; 53 54 return 0; 55 }
编译执行: