C++系列十:日常学习-智能指针

介绍:

智能指针是一种存储指向动态分配(堆)对象指针的类。除了能够在适当的时间自动删除指向的对象外,它们的工作机制与C++的内置指针类似。智能指针在面对异常或者未定义行为时特别有用,它们能够确保正确的销毁动态分配的对象。

在C++标准库中,有几种类型的智能指针,包括:

  1. std::auto_ptr:这是为解决资源所有权问题而设计的,但有一个重大缺陷:当拷贝构造时,所有权会被转移,而原始指针会被设置为nullptr。这在对数组进行操作时可能会导致问题,因为数组需要有一个单一的所有者。

  2. std::unique_ptr:这是一种独占所有权的智能指针,它允许唯一地拥有和操作动态分配的对象。当unique_ptr离开作用域或者被重置时,它会自动删除所指向的对象。这避免了内存泄漏和悬挂指针的问题。

  3. std::shared_ptr:这是一种共享所有权的智能指针。多个shared_ptr可以指向同一个动态分配的对象,并且当最后一个shared_ptr离开作用域或者被重置时,它会自动删除所指向的对象。这解决了在多用户情况下共享动态分配对象的所有权问题。

  4. std::weak_ptr:这是一种从属智能指针,它允许你访问shared_ptr所指向的对象,但不会增加对该对象的引用计数。这解决了循环引用的问题,因为你可以使用weak_ptr来访问对象,但不会增加其引用计数,防止程序长时间无法释放资源。
    这些智能指针可以用于实现各种功能,例如处理线程安全、提供写时复制、确保协议以及提供远程交互服务。

  5. 此外,还有一些非标准的智能指针,如Boost库中的scoped_ptr、scoped_array、shared_array和weak_ptr,它们提供了一些额外的功能和性能优化。

案例:

//std::auto_ptr
std::auto_ptr<int> p1(new int(42));
std::cout << "p1 points to " << *p1 << std::endl;
std::auto_ptr<int> p2 = p1; // p1失去所有权,p2获得所有权  
std::cout << "p1 points to " << p1.get() << ", p2 points to " << *p2 << std::endl;

//result:
//p1 points to 42
//p1 points to 0000000000000000, p2 points to 42
//explain:
//在上面的例子中,p1创建了一个动态分配的整数,并将其所有权传递给了p2。当p2被输出时,p1已经失去了所有权,指向的内存已经被释放,因此输出为0。

//unique_ptr:
std::unique_ptr<int> p1(new int(42));  
std::cout << "p1 points to " << *p1 << std::endl;  
std::unique_ptr<int> p2 = std::move(p1); // p1失去所有权,p2获得所有权  
std::cout << "p1 points to " << p1.get() << ", p2 points to " << *p2 << std::endl; 

//result:
//p1 points to 42  
//p1 points to nullptr, p2 points to 42
//explain:
//在上面的例子中,p1创建了一个动态分配的整数,并将其所有权通过移动赋值操作符传递给了p2。当p2被输出时,p1已经失去了所有权,指向的内存已经被释放,因此输出为nullptr。


//shared_ptr
std::shared_ptr<int> p1(new int(42));  
std::cout << "p1 points to " << *p1 << std::endl;     
std::shared_ptr<int> p2 = p1; // p1和p2共享所有权  
std::cout << "p1 points to " << p1.get() << ", p2 points to " << *p2 << std::endl;     
p2.reset(); // p2失去所有权,p1成为唯一指向该对象的指针  
std::cout << "p1 points to " << p1.get() << std::endl;  

//result:
//p1 points to 42
//p1 points to 000001A2818D72C0, p2 points to 42
//p1 points to 000001A2818D72C0
posted @ 2023-09-05 19:33  cactus9  阅读(31)  评论(0编辑  收藏  举报