Boost学习笔记 -- memory management

本文介绍了C++中智能指针的概念及应用,包括scoped_ptr、shared_ptr等类型的使用方法,并探讨了它们如何帮助开发者更好地管理内存资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RAII机制

为了管理内存等资源,C++程序员通常采用RAII机制(资源获取即初始化,Resource Acquisition Is Initialization ),在使用资源的类的构造函数中申请资源,然后使用,最后在析构函数中释放资源。
如果对象是在栈上创建的,RAII机制可以正常工作;但如果对象是使用new在堆上创建的,那么析构函数不会自动调用,程序员必须明确使用delete来释放资源。

智能指针

boost.smart_ptr库提供了6种智能指针:

  • scoped_ptr
  • shared_ptr
  • intrusive_ptr
  • weak_ptr
  • scoped_array
  • shared_array

使用方法

#include <boost/smart_ptr.hpp>
using namespace boost;

scoped_ptr

scoped_ptr的所有权很严格,不能转让,一旦scoped_ptr获取了对象的管理权,你就无法再从它那里取回来。

scoped_ptr<string> sp( new string( "text" ) );
cout << *sp << endl;
cout << sp->size() << endl;
sp++;   // wrong, scoped_ptr未定义递增操作符
scoped_ptr<string> sp2 = sp;    //wrong, scoped_ptr不能拷贝构造
struct poxist_file {
    posix_file( const char* file_name ) {
        cout << "open file: " << file_name << endl;
    }
    ~posix_file() {
        cout << "close file" << endl;
    }
}

int main() {
    scoped_ptr<int> p( new int );
    if( p ) {
        *p = 100;
        cout << *p << endl;
    }

    p.reset();
    assert( p == 0 );
    if( !p ) {
        cout << "scoped_ptr == null" << endl;
    }

    // 将在离开作用域时自动析构,从而关闭文件释放资源
    scoped_ptr<posix_file> fp( new posix_file( "/tmp/a.txt" ) );
}   // p和fp的指针自动被删除

result:
100
scoped_ptr == null
open file: /tmp/a.txt
close file

scoped_array

scoped_array很像scoped_ptr,包装了new[]操作符,它为动态数组提供了一个代理,保证内存正确释放。

int main() {
    int* arr = new int[ 100 ];
    scoped_array<int> sa( arr );

    fill_n( &sa[ 0 ], 100, 5 );
    sa[ 10 ] = sa[ 20 ] + sa[ 30 ];
}

如果可以使用STL的话,在需要动态数组的情况下我们使用std::vector,它比scoped_array提供了更多的灵活性,而只付出了很小的代价。

shared_ptr

shared_ptr是实现了引用计数的智能指针,可以被自由地拷贝和赋值,在任意的地方共享他,当没有代码使用(引用计数为0)时才删除被包装的动态内存。

shared_ptr<int> sp( new int( 10 ) );
assert( sp.unique() );

shared_ptr<int> sp2 = sp;

assert( sp == sp2 && sp.use_count() == 2 );
*sp2 = 100;
assert( *sp == 100 );

sp.reset();
assert( !sp );
class shared {
private:
    shared_ptr<int> p;
public:
    shared( shared_ptr<int> p_):p( p_ ) {}
    void print() {
        cout << "count:" << p.use_count() << "v = " << *p << endl;
    }
};

void print_func( shared_ptr<int> p ) {
    cout << "count:" << p.use_count() << " v =" << *p << endl;
}

int main() {
    shared_ptr<int> p( new int( 100 ) );
    shared s1( p ), s2( p );

    s1.print();
    s2.print();

    *p = 20;
    print_func( p );

    s1.print();
}

注意,print_func()的参数是值传递,没有使用引用,所以最后输出如下:
count: 3 v = 100
count: 3 v= 100
count: 4 v= 20
count: 3 v = 20

工厂函数

shared_ptr的构造需要使用new,这导致了代码的不对称性(不需要使用delete),shared_ptr提供了一个工厂函数make_shared()来消除显式的new调用。

#include <boost/make_shared.hpp>

int main() {
    typedef vector< shared_ptr< int > > vs;
    vs v( 10 );

    int i = 0;
    for( vs::iterator pos = v.begin(); pos != v.end(); ++pos ) {
        ( *pos ) = make_shared< int >( ++i );
        cout << *( *pos ) << ", ";
    }
    cout << endl;

    shared_ptr< int > p = v[ 9 ];
    *p = 100;
    cout << v[ 9 ] << endl;

    // using boost.foreach
    for( auto& ptr : v ) {
        ptr = make_shared< int >( ++i );
        cout << *ptr << ", ";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值