boost库之智能指针(一)
一、boost::scoped_ptr
boost::scoped_ptr
是Boost库中的一个智能指针类,用于管理动态分配的对象,并确保在超出作用域时自动释放资源。boost::scoped_ptr
提供了一种简单而安全的方式来管理对象的生命周期。它的行为类似于C++原始指针,但它负责在其生命周期结束时自动调用delete来释放所管理的对象。它是一个非共享指针,即不能进行拷贝构造或赋值操作,这样可以避免多个指针同时删除同一个对象的问题。
它具有以下特点:
-
所有权和生命周期管理:
boost::scoped_ptr
负责管理动态分配对象的生命周期。它在析构函数中使用delete
来释放所管理的对象内存,确保对象在超出作用域时被正确释放。 -
自动删除:与原始指针不同,
boost::scoped_ptr
会自动释放所管理的对象内存,无需手动调用delete
。这避免了因忘记或错误地释放对象内存而导致的内存泄漏问题。 -
非共享指针:
boost::scoped_ptr
是一个非共享指针,不支持拷贝构造和赋值操作。每个boost::scoped_ptr
对象拥有独立的对象所有权,确保对象的所有权不会被意外地转移或共享。 -
单个对象管理:
boost::scoped_ptr
适用于管理动态分配的单个对象,而不是数组。它提供了对对象的访问和释放等操作。
示例演示:
#include <iostream> #include <boost/scoped_ptr.hpp> class SmartPointers { public: SmartPointers():m_value(0) { std::cout << "智能指针构造函数" << std::endl; } ~SmartPointers() { std::cout << "智能指针析构函数" << std::endl; } public: void setValue(int value) { m_value = value; } int getValue() { return m_value; } private: int m_value; }; void test() { boost::scoped_ptr<SmartPointers> smartPointer(new SmartPointers); smartPointer->setValue(10); std::cout << smartPointer->getValue() << std::endl; } int main() { test(); return 0; }
打印结果:
可以看出当离开test()作用域后,调用了SmartPointers的析构函数,说明boost::scoped_ptr调用了delete释放了内存
boost::scoped_ptr部分源码:
private: scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); void operator==( scoped_ptr const& ) const; void operator!=( scoped_ptr const& ) const;
从上述源码中可以看出boost::scoped_ptr 是一个非共享指针,即不能进行拷贝构造或赋值操作。这意味着每个 boost::scoped_ptr 对象拥有独立的所有权,避免了资源释放的重复和悬挂指针的问题。
boost::scoped_ptr常用操作:
/* 用一个新的对象来重新初始化智能指针 */ void reset(T * p = 0) /* 以引用的形式访问所管理的对象的成员 */ T & operator*() /* 以指针的形式访问所管理的对象的成员 */ T * operator->() /* 获取所含对象的指针 */ T * get() /* 交换两个boost::scoped_ptr管理的对象 */ void swap(scoped_ptr & b)
示例演示:
void test() { boost::scoped_ptr<SmartPointers> smartPointer(new SmartPointers); smartPointer->setValue(10); std::cout << "----------交换前----------" << std::endl; std::cout << smartPointer->getValue() << std::endl; std::cout << smartPointer.get()->getValue() << std::endl; std::cout << (*smartPointer).getValue() << std::endl; boost::scoped_ptr<SmartPointers> smartPointer_1(new SmartPointers); smartPointer_1->setValue(20); smartPointer.swap(smartPointer_1); std::cout << "----------交换后----------" << std::endl; std::cout << smartPointer->getValue() << std::endl; std::cout << smartPointer_1->getValue() << std::endl; }
打印结果:
二、boost::scoped_array
boost::scoped_array
是 Boost 库中提供的一个智能指针类,用于管理动态分配的数组内存。它具有类似于 boost::scoped_ptr
的特点,但专门用于管理数组而不是单个对象。boost::scoped_array
主要特点如下:
-
所有权和生命周期管理:
boost::scoped_array
负责管理动态分配的数组的生命周期。它在析构函数中使用delete[]
来释放所管理的数组内存,确保数组在超出作用域时被正确释放。 -
自动删除:与原始指针不同,
boost::scoped_array
会自动释放所管理的数组内存,无需手动调用delete[]
。这避免了因忘记或错误地释放数组内存而导致的内存泄漏问题。 -
非共享指针:
boost::scoped_array
是一个非共享指针,不支持拷贝构造和赋值操作。每个boost::scoped_array
对象拥有独立的数组所有权,确保数组的所有权不会被意外地转移或共享。 -
动态数组管理:
boost::scoped_array
适用于管理动态分配的数组,而不是单个对象。它提供了对数组元素的访问、遍历和释放等操作。 -
使用方式:使用
boost::scoped_array
类时,首先需要通过boost::scoped_array<T>
(其中 T 是数组元素的类型)创建一个boost::scoped_array
对象。可以使用new
运算符动态分配一个数组,并将其传递给boost::scoped_array
的构造函数。然后,可以通过operator[]
来访问数组元素,使用类似于原始数组的语法。
示例演示:
void test() { boost::scoped_array<SmartPointers> intArray(new SmartPointers[2]); intArray[0].setValue(10); intArray[1].setValue(20); std::cout << intArray.get()[0].getValue() << std::endl; std::cout << intArray.get()[1].getValue() << std::endl; } int main() { test(); return 0; }
打印结果:
三、boost::shared_ptr
boost::shared_ptr
是 Boost 库中提供的一个智能指针类,用于管理动态分配的对象的内存。它具有以下特点:
-
所有权和生命周期管理:
boost::shared_ptr
实现了引用计数机制,多个shared_ptr
对象可以共享同一个对象的所有权。它会在没有引用时自动释放所管理的对象内存,通过跟踪引用计数来确定何时释放内存。 -
自动删除:与原始指针不同,
boost::shared_ptr
会自动释放所管理的对象内存,无需手动调用delete
。这避免了因忘记或错误地释放对象内存而导致的内存泄漏问题。 -
共享指针:
boost::shared_ptr
支持拷贝构造和赋值操作,多个shared_ptr
对象可以指向同一个对象。当所有shared_ptr
对象超出作用域或被显式重置时,引用计数减少,只有当引用计数为零时,对象内存才会被释放。 -
异常安全:
boost::shared_ptr
提供了异常安全的内存管理。即使在异常抛出的情况下,也能保证对象内存被正确释放,防止资源泄漏。 -
自定义删除器:
boost::shared_ptr
允许指定一个自定义的删除器函数或函数对象来替代默认的delete
操作符,以满足特殊的内存管理需求。
示例演示:
void test() { /* boost::shared_ptr初始化方式 */ boost::shared_ptr<SmartPointers> smartPointer = boost::make_shared<SmartPointers>(); //boost::shared_ptr<SmartPointers> smartPointer1(new SmartPointers()); //boost::shared_ptr<SmartPointers> smartPointer2 = boost::shared_ptr<SmartPointers>(new SmartPointers()); smartPointer->setValue(10); std::cout << "smartPointer->getValue():" << smartPointer->getValue() << std::endl; boost::shared_ptr<SmartPointers> smartPointer1(smartPointer); std::cout << "smartPointer1->getValue():" << smartPointer1->getValue() << std::endl; smartPointer.reset(new SmartPointers()); std::cout << "smartPointer->getValue():" << smartPointer->getValue() << std::endl; std::cout << "smartPointer.use_count():" << smartPointer.use_count() << std::endl; } int main() { test(); return 0; }
打印结果:
类似于boost::scoped_ptr,boost::shared_ptr也重载了operator*(),operator()->,另外还可以通过get()和reset()函数来获取和重新初始化所包含的对象的地址。从上述代码中调用smartPointer.reset(new SmartPointers())后,smartPointer之前的对象并没有被释放,因为smartPointer1还在引用它,只是引用计数减少了,boost::shared_ptr记录了多少共享指针在引用一个对象,只有最后一个共享指针销毁时,也就是当引用计数为0时,才会释放这个对象。
四、指针容器
多数时候,这些对象都是要存储在容器里:
int main() { std::vector<boost::shared_ptr<SmartPointers>> ptr_vector; ptr_vector.push_back(boost::make_shared<SmartPointers>()); ptr_vector.push_back(boost::make_shared<SmartPointers>()); return 0; }
但是因为某些原因,实际情况中并不这么使用,首先反复声明boost::shared_ptr需要更多的输入,其次将boost::shared_ptr拷进,拷出或者在容器内部做拷贝,需要频繁的增加或者减少内部引用计数,效率肯定不高,所以Boost库提供了指针容器专门用来管理动态分配的对象
#include <boost/ptr_container/ptr_vector.hpp> int main() { boost::ptr_vector<SmartPointers> ptr; ptr.push_back(new SmartPointers()); ptr.push_back(new SmartPointers()); return 0; }
boost::ptr_vector专门用于动态分配对象,它用起来更容易也更高效,boost::ptr_vector独占它所包含的对象,因而容器之外的共享指针不能共享所有权。除了boost::ptr_vector之外,专门用于管理动态分配对象的容器还包括:boost::ptr_deque,boost::ptr_list,boost::ptr_set,boost::ptr_map。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?