boost库之智能指针(一)

一、boost::scoped_ptr

boost::scoped_ptr是Boost库中的一个智能指针类,用于管理动态分配的对象,并确保在超出作用域时自动释放资源。boost::scoped_ptr提供了一种简单而安全的方式来管理对象的生命周期。它的行为类似于C++原始指针,但它负责在其生命周期结束时自动调用delete来释放所管理的对象。它是一个非共享指针,即不能进行拷贝构造或赋值操作,这样可以避免多个指针同时删除同一个对象的问题。

它具有以下特点:

  1. 所有权和生命周期管理:boost::scoped_ptr 负责管理动态分配对象的生命周期。它在析构函数中使用 delete 来释放所管理的对象内存,确保对象在超出作用域时被正确释放。

  2. 自动删除:与原始指针不同,boost::scoped_ptr 会自动释放所管理的对象内存,无需手动调用 delete。这避免了因忘记或错误地释放对象内存而导致的内存泄漏问题。

  3. 非共享指针:boost::scoped_ptr 是一个非共享指针,不支持拷贝构造和赋值操作。每个 boost::scoped_ptr 对象拥有独立的对象所有权,确保对象的所有权不会被意外地转移或共享。

  4. 单个对象管理: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 主要特点如下:

  1. 所有权和生命周期管理:boost::scoped_array 负责管理动态分配的数组的生命周期。它在析构函数中使用 delete[] 来释放所管理的数组内存,确保数组在超出作用域时被正确释放。

  2. 自动删除:与原始指针不同,boost::scoped_array 会自动释放所管理的数组内存,无需手动调用 delete[]。这避免了因忘记或错误地释放数组内存而导致的内存泄漏问题。

  3. 非共享指针:boost::scoped_array 是一个非共享指针,不支持拷贝构造和赋值操作。每个 boost::scoped_array 对象拥有独立的数组所有权,确保数组的所有权不会被意外地转移或共享。

  4. 动态数组管理:boost::scoped_array 适用于管理动态分配的数组,而不是单个对象。它提供了对数组元素的访问、遍历和释放等操作。

  5. 使用方式:使用 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 库中提供的一个智能指针类,用于管理动态分配的对象的内存。它具有以下特点:

  1. 所有权和生命周期管理:boost::shared_ptr 实现了引用计数机制,多个 shared_ptr 对象可以共享同一个对象的所有权。它会在没有引用时自动释放所管理的对象内存,通过跟踪引用计数来确定何时释放内存。

  2. 自动删除:与原始指针不同,boost::shared_ptr 会自动释放所管理的对象内存,无需手动调用 delete。这避免了因忘记或错误地释放对象内存而导致的内存泄漏问题。

  3. 共享指针:boost::shared_ptr 支持拷贝构造和赋值操作,多个 shared_ptr 对象可以指向同一个对象。当所有 shared_ptr 对象超出作用域或被显式重置时,引用计数减少,只有当引用计数为零时,对象内存才会被释放。

  4. 异常安全:boost::shared_ptr 提供了异常安全的内存管理。即使在异常抛出的情况下,也能保证对象内存被正确释放,防止资源泄漏。

  5. 自定义删除器: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。

posted @   TechNomad  阅读(269)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示