对象的生存期:
全局对象:程序启动时创建,程序结束时销毁 局部自动对象:进入对象所在程序块时创建,离开程序块时销毁 static
对象:第一次使用时创建,程序结束时销毁动态分配的对象:创建之后只有在显式地被释放 时才会销毁
每个程序拥有一个内存池,称为自由空间或堆 ,用来存储动态分配的对象
智能指针
传统的动态内存管理:
new
:在动态内存中为对象分配空间,返回一个指向该对象的指针delete
:接受一个动态对象的指针,销毁该对象,释放内存 智能指针:
#include <memory>
智能指针是模板类,创建智能指针时需要提供具体的类型 shared_ptr
:允许多个指针指向同一个对象unique_ptr
:“独占”所指向的对象shared_ptr
和 unique_ptr
都支持的操作
shared_ptr< T> sp_T;
unique_ptr< T> up_T;
* sp_T, * up_T
sp_T-> mem, up_T-> mem
swap ( p1, p2) , p1. swap ( p2)
shared_ptr
shared_ptr< int > sp_int;
shared_ptr< vector< string> sp_str_vec;
shared_ptr
独有的操作
make_shared< T> ( args)
shared_ptr< T> sp2 ( sp1)
sp2 = sp1
sp. unique ( )
sp. use_count ( )
make_shared<T>(args)
最安全的分配和使用动态内存的方法 在内存中分配一个 T
类型的对象,使用 args
初始化该对象,并返回指向该对象的 shared_ptr
shared_ptr< int > sp_int = make_shared< int > ( 1024 ) ;
shared_ptr< string> sp_str = make_shared< string> ( "Hello, world!" ) ;
shared_ptr< vector< double >> sp_dbl_vec = make_shared< vector< double >> ( vector< double > ( { 3.14159 , 1.414 , 1.732 } ) ) ;
list< int > int_lst{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
auto sp_int_lst = make_shared< list< int >> ( int_lst) ;
shared_ptr
的赋值和拷贝
进行赋值和拷贝时,每个 shared_ptr
都会记录指向相同对象的其他 shared_ptr
的数量 每进行一次赋值和拷贝,shared_ptr
指向的对象的引用计数都会递增 当给 shared_ptr
赋予一个新值,或是 shared_ptr
被销毁时,其原来所指向的对象 的引用计数会递减 当一个 shared_ptr
指向的对象的引用计数变为 0 时,便自动释放该对象
auto sp_int1 = make_shared< int > ( 1024 ) ;
auto sp_int2 = sp_int1;
使用 shared_ptr
实现多个对象之间共享数据
一个对象的成员在对象销毁时也会被销毁;将数据保存在动态内存中,可以实现对象销毁时的数据保留
class StrBlob {
public:
typedef vector< string> : : size_type size_type;
StrBlob ( ) ;
StrBlob ( initializer_list< string> str_ilist) ;
size_type size ( ) const { return data-> size ( ) ; }
bool empty ( ) const { return data-> empty ( ) ; }
void push_back ( const string & str) { data-> push_back ( str) ; }
void pop_back ( ) ;
string & front ( ) ;
string & back ( ) ;
shared_ptr< vector< string>> data;
private:
void check ( size_type i, const string & msg) const ;
} ;
StrBlob: : StrBlob ( ) : data ( make_shared< vector< string>> ( ) ) { }
StrBlob: : StrBlob ( initializer_list< string> str_ilist) : data ( make_shared< vector< string>> ( str_ilist) ) { }
void StrBlob: : check ( size_type i, const string & msg) const {
if ( i >= data-> size ( ) )
throw out_of_range ( msg) ;
}
string & StrBlob: : front ( ) {
check ( 0 , "front on empty StrBlob" ) ;
return data-> front ( ) ;
}
string & StrBlob: : back ( ) {
check ( 0 , "front on empty StrBlob" ) ;
return data-> back ( ) ;
}
void StrBlob: : pop_back ( ) {
check ( 0 , "pop_back on empty StrBlob" ) ;
data-> pop_back ( ) ;
}
int main ( )
{
StrBlob strblob1;
{
StrBlob strblob2 ( { "Hello, " , "welcome " , "to " , "the " , "C++ " , "world." } ) ;
cout << strblob2. data << " : " << strblob2. front ( ) << endl;
strblob1 = strblob2;
cout << strblob1. data << " : " << strblob1. front ( ) << endl;
}
cout << strblob1. data << " : " << strblob1. front ( ) << endl;
cin. get ( ) ;
return 0 ;
}
unique_ptr
一个 unique_ptr
“独占”它所指向的内存,也就是说,在任一时刻,最多只能有一个 unique_ptr
指向一个给定对象 当一个 unique_ptr
被销毁时,其所指的对象也被销毁
unique_ptr
独有的操作
unique_ptr< T> up1;
unique_ptr< T, D> up2;
unique_ptr< T, D> up3 ( d) ;
up = nullptr;
up. release ( ) ;
up. reset ( ) ;
up. reset ( q) ;
up. reset ( nullptr) ;
定义一个 unique_ptr
时,需要将其绑定到一个 new 返回的指针 unique_ptr
不支持普通的赋值和拷贝操作
unique_ptr< double > up_dbl;
unique_ptr< int > up_int ( new int ( 1024 ) ) ;
unique_ptr< string> up_str1 ( new string ( "Hello, world!" ) ) ;
unique_ptr< vector< string>> up_str_vec ( new vector< string> ( { "Hello, " , "world!" } ) ) ;
unique_ptr< string> up_str2 ( up_str1. release ( ) ) ;
unique_ptr< string> up_str3 ( new string ( "Welcome to the C++ world." ) ) ;
up_str2. reset ( up_str3. release ( ) ) ;