402 创建智能指针
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
using namespace std;
int main ( ) {
shared_ptr< string> p1;
shared_ptr< list< int >> p2;
if ( p1-> empty ( ) )
* p1 = "hi" ;
shared_ptr< int > p3 = make_shared< int > ( 42 ) ;
shared_ptr< string> p4 = make_shared< string> ( 10 , '9' ) ;
shared_ptr< int > p5 = make_shared< int > ( ) ;
auto p6 = make_shared< vector< string>> ( ) ;
auto p = make_shared< int > ( 42 ) ;
auto q ( p) ;
auto r = make_shared< int > ( 42 ) ;
r = q;
return 0 ;
}
402 智能指针例子
int main ( ) {
initializer_list< string> lst = { "a" , "b" , "c" } ;
shared_ptr< initializer_list< string>> li = make_shared< initializer_list< string>> ( lst) ;
cout << * li-> begin ( ) << endl;
int num = 1 ;
shared_ptr< int > pi = make_shared< int > ( num) ;
cout << * pi << endl;
return 0 ;
}
405 复习一下在类外定义构造函数
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
using namespace std;
class Sales_data {
public :
Sales_data ( ) ;
Sales_data ( const string & s) ;
string show_data ( ) {
return this -> data;
}
private :
string data;
} ;
Sales_data :: Sales_data ( ) : data ( string ( "sdds" ) ) { }
Sales_data :: Sales_data ( const string & s) : data ( s) { } ;
int main ( ) {
Sales_data demo;
cout << demo. show_data ( ) << endl;
return 0 ;
}
StrBlob类
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
using namespace std;
class StrBlob {
public :
typedef std:: vector< std:: string> :: size_type size_type;
StrBlob ( ) ;
StrBlob ( std:: initializer_list< std:: string> il) ;
size_type size ( ) const { return data-> size ( ) ; } ;
bool empty ( ) const { return data-> empty ( ) ; } ;
void push_back ( const std:: string & t) { data-> push_back ( t) ; } ;
void pop_back ( ) ;
std:: string& front ( ) ;
std:: string& back ( ) ;
private :
std:: shared_ptr< std:: vector< std:: string>> data;
void check ( size_type i, const std:: string & msg) const ;
} ;
StrBlob :: StrBlob ( ) : data ( make_shared< vector< string>> ( ) ) { }
StrBlob :: StrBlob ( initializer_list< string> il) : data ( make_shared< vector< string>> ( il) ) { }
void StrBlob :: check ( size_type i, const std:: 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 , "back on empty StrBlob" ) ;
return data-> back ( ) ;
}
void StrBlob :: pop_back ( ) {
check ( 0 , "pop_back on empty StrBlob" ) ;
data-> pop_back ( ) ;
}
int main ( ) {
initializer_list< string> s = { "1" , "2" , "3" } ;
StrBlob demo ( s) ;
cout << demo. front ( ) << endl;
cout << demo. back ( ) << endl;
demo. pop_back ( ) ;
cout << demo. size ( ) << endl;
cout << demo. back ( ) << endl;
return 0 ;
}
407 动态内存分配和初始化对象
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
int main ( ) {
int * pi = new int ;
string * ps = new string;
int * pi2 = new int ( 1024 ) ;
string * ps2 = new string ( 10 , '9' ) ;
vector< int > * pv2 = new vector< int > { 0 , 1 , 2 , 3 } ;
string * ps3 = new string;
string * ps4 = new string ( ) ;
int * pi3 = new int ;
int * pi4 = new int ( ) ;
int num1 = 2 ;
int * pi5 = new auto ( num1) ;
const int * pci = new const int ( 1024 ) ;
const string * pcs = new const string;
return 0 ;
}
delete
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
int main ( ) {
int * p1 = new int ;
int * p2 = new ( nothrow) int ;
int num = 3 ;
int * p3 = & num;
int i, * pi1 = & i, * pi2 = nullptr ;
double * pd = new double ( 33 ) , * pd2 = pd;
delete pd;
delete pi2;
return 0 ;
}
动态内存例子
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
int main ( ) {
int * p1 = new int ;
int * p2 = new ( nothrow) int ;
int num = 3 ;
int * p3 = & num;
int i, * pi1 = & i, * pi2 = nullptr ;
double * pd = new double ( 33 ) , * pd2 = pd;
delete pd;
delete pi2;
const int * pci = new const int ( 1024 ) ;
delete pci;
return 0 ;
}
411 动态内存的坑
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
int main ( ) {
int * p ( new int ( 42 ) ) ;
auto q = p;
delete p;
p = nullptr ;
return 0 ;
}
12.6
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
vector< int > * create ( ) {
return new vector< int > ;
}
int main ( ) {
vector< int > * pv = create ( ) ;
vector< int > vec = { 1 , 2 , 3 } ;
for ( auto val: vec) {
pv-> push_back ( val) ;
}
for ( vector< int > :: iterator iter= pv-> begin ( ) ; iter!= pv-> end ( ) ; ++ iter) {
cout << * iter << " " ;
}
delete pv;
return 0 ;
}
12.7
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
shared_ptr< vector< int >> create ( ) {
return make_shared< vector< int >> ( ) ;
}
int main ( ) {
shared_ptr< vector< int >> pv = create ( ) ;
vector< int > vec = { 1 , 2 , 3 } ;
for ( auto val: vec) {
pv-> push_back ( val) ;
}
for ( vector< int > :: iterator iter= pv-> begin ( ) ; iter!= pv-> end ( ) ; ++ iter) {
cout << * iter << " " ;
}
return 0 ;
}
412 智能指针和动态内存结合使用
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
shared_ptr< int > clone ( int p) {
return shared_ptr< int > ( new int ( p) ) ;
}
int main ( ) {
shared_ptr< double > p1;
shared_ptr< int > p2 ( new int ( 42 ) ) ;
shared_ptr< int > p3 ( new int ( 1024 ) ) ;
return 0 ;
}
413 不要混合使用智能指针和普通指针
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
void process ( shared_ptr< int > ptr) {
}
int main ( ) {
int * x ( new int ( 1024 ) ) ;
cout << * x << endl;
process ( shared_ptr< int > ( x) ) ;
int j = * x;
cout << j << endl;
return 0 ;
}
判断智能指针是否共享对象
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
using namespace std;
int main ( ) {
shared_ptr< int > p ( new int ( 42 ) ) ;
int * q = p. get ( ) ;
{
shared_ptr< int > ( q) ;
}
cout << * p << endl;
p. reset ( new int ( 1024 ) ) ;
shared_ptr< int > p2 = p;
if ( ! p. unique ( ) ) {
cout << "p not unique" << endl;
}
return 0 ;
}
12.14 重写share_ptr综合例子,连接程序
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
# include <string>
using namespace std;
struct destination {
string des;
destination ( string des_) : des ( des_) { }
} ;
struct connection {
string conn;
connection ( string conn_) : conn ( conn_) { }
} ;
connection connect ( destination * des_) {
connection conn ( des_-> des) ;
cout << "connect to " << des_-> des << endl;
return conn;
}
void disconnect ( connection * conn) {
cout << "disconnect " << conn-> conn << endl;
}
void end_connection ( connection * p) {
disconnect ( p) ;
}
void f ( destination * des) {
connection conn = connect ( des) ;
shared_ptr< connection> p ( & conn, end_connection) ;
cout << "connecting " << des-> des << " now" << endl;
}
int main ( ) {
destination des ( "aa" ) ;
f ( & des) ;
return 0 ;
}
12.15
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
# include <string>
using namespace std;
struct destination {
string des;
destination ( string des_) : des ( des_) { }
} ;
struct connection {
string conn;
connection ( string conn_) : conn ( conn_) { }
} ;
connection connect ( destination * des_) {
connection conn ( des_-> des) ;
cout << "connect to " << des_-> des << endl;
return conn;
}
void disconnect ( connection * conn) {
cout << "disconnect " << conn-> conn << endl;
}
void f ( destination * des) {
connection conn = connect ( des) ;
shared_ptr< connection> p ( & conn, [ ] ( connection * p) { disconnect ( p) ; } ) ;
cout << "connecting " << des-> des << " now" << endl;
}
int main ( ) {
destination des ( "aa" ) ;
f ( & des) ;
return 0 ;
}
417 unique_ptr
# include <iostream>
# include <memory>
# include <string>
using namespace std;
int main ( ) {
unique_ptr< double > p1;
unique_ptr< int > p2 ( new int ( 42 ) ) ;
unique_ptr< string> p3 ( new string ( "aaabbbccc" ) ) ;
unique_ptr< string> p5;
return 0 ;
}
unique_pt的控制权迁移
# include <iostream>
# include <memory>
# include <string>
using namespace std;
int main ( ) {
unique_ptr< string> p1 ( new string ( "ssss" ) ) ;
unique_ptr< string> p2 ( p1. release ( ) ) ;
unique_ptr< string> p3 ( new string ( "aaaa" ) ) ;
p2. reset ( p3. release ( ) ) ;
cout << * p2 << endl;
auto p = p2. release ( ) ;
delete p;
return 0 ;
}
419 使用unique_ptr写连接程序
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
# include <string>
using namespace std;
struct destination {
string des;
destination ( string des_) : des ( des_) { }
} ;
struct connection {
string conn;
connection ( string conn_) : conn ( conn_) { }
} ;
connection connect ( destination * des_) {
connection conn ( des_-> des) ;
cout << "connect to " << des_-> des << endl;
return conn;
}
void disconnect ( connection * conn) {
cout << "disconnect " << conn-> conn << endl;
}
void end_connection ( connection * p) {
disconnect ( p) ;
}
void f ( destination * des) {
connection conn = connect ( des) ;
unique_ptr< connection, decltype ( end_connection) * > p ( & conn, end_connection) ;
cout << "connecting " << des-> des << " now" << endl;
}
int main ( ) {
destination des ( "aa" ) ;
f ( & des) ;
return 0 ;
}
420 weak_ptr 弱共享
# include <iostream>
# include <memory>
# include <malloc.h>
# include <vector>
# include <string>
using namespace std;
int main ( ) {
auto p = make_shared< int > ( 42 ) ;
shared_ptr< int > p2 ( p) ;
weak_ptr< int > wp ( p) ;
cout << p. use_count ( ) << endl;
if ( shared_ptr< int > np = wp. lock ( ) ) {
cout << * np << endl;
}
return 0 ;
}
12.19 - 12.20
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
class StrBlob {
public :
friend class StrBlobPtr ;
StrBlobPtr begin ( ) ;
StrBlobPtr end ( ) ;
typedef std:: vector< std:: string> :: size_type size_type;
StrBlob ( ) ;
StrBlob ( std:: initializer_list< std:: string> il) ;
size_type size ( ) const { return data-> size ( ) ; } ;
bool empty ( ) const { return data-> empty ( ) ; } ;
void push_back ( const std:: string & t) { data-> push_back ( t) ; } ;
void pop_back ( ) ;
std:: string& front ( ) ;
std:: string& back ( ) ;
std:: shared_ptr< std:: vector< std:: string>> data;
private :
void check ( size_type i, const std:: string & msg) const ;
} ;
StrBlob :: StrBlob ( ) : data ( make_shared< vector< string>> ( ) ) { }
StrBlob :: StrBlob ( initializer_list< string> il) : data ( make_shared< vector< string>> ( il) ) { }
void StrBlob :: check ( size_type i, const std:: 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 , "back on empty StrBlob" ) ;
return data-> back ( ) ;
}
void StrBlob :: pop_back ( ) {
check ( 0 , "pop_back on empty StrBlob" ) ;
data-> pop_back ( ) ;
}
class StrBlobPtr {
public :
StrBlobPtr ( ) : curr ( 0 ) { }
StrBlobPtr ( StrBlob & a, size_t sz= 0 ) : wptr ( a. data) , curr ( sz) { }
string& deref ( ) const ;
StrBlobPtr& incr ( ) ;
private :
shared_ptr< vector< string>> check ( size_t, const string& ) const ;
weak_ptr< vector< string>> wptr;
size_t curr;
} ;
shared_ptr< vector< string>> StrBlobPtr :: check ( size_t i, const string & msg) const {
auto ret = wptr. lock ( ) ;
if ( ! ret) {
throw runtime_error ( "unbound StrBlobPtr" ) ;
}
if ( i>= ret-> size ( ) )
throw out_of_range ( msg) ;
return ret;
}
string& StrBlobPtr :: deref ( ) const {
auto p = check ( curr, "dereference past end" ) ;
return ( * p) [ curr] ;
}
StrBlobPtr& StrBlobPtr :: incr ( ) {
check ( curr, "increment past end of StrBlobPtr" ) ;
++ curr;
return * this ;
}
StrBlobPtr StrBlob :: begin ( ) {
return StrBlobPtr ( * this ) ;
}
StrBlobPtr StrBlob :: end ( ) {
return StrBlobPtr ( * this , data-> size ( ) ) ;
}
int main ( ) {
StrBlob stb;
StrBlobPtr stbr ( stb) ;
ifstream in ( "items.txt" ) ;
string text;
while ( getline ( in , text) ) {
stb. push_back ( text) ;
cout << text << endl;
}
cout << endl;
auto begin = stb. begin ( ) ;
auto end = stb. end ( ) ;
while ( true ) {
try {
cout << stbr. deref ( ) << endl;
stbr. incr ( ) ;
} catch ( . . . ) {
cout << "end of data" << endl;
break ;
}
}
return 0 ;
}
423 动态数组的创建
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
int * pia = new int [ 30 ] ;
typedef int arrT[ 42 ] ;
int * p = new arrT ;
int * pia2 = new int [ 10 ] ( ) ;
for ( size_t i= 0 ; i!= 10 ; ++ i) {
cout << * ( pia2+ i) << " " ;
}
cout << endl;
int * pia3 = new int [ 10 ] { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
string * psa3 = new string[ 10 ] { "a" , "an" , "the" , string ( 3 , 'x' ) } ;
for ( size_t i= 0 ; i!= 10 ; ++ i) {
cout << * ( psa3+ i) << " " ;
}
cout << endl;
return 0 ;
}
425 释放动态数组
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
int * p = new int [ 10 ] ;
delete [ ] p;
int * p2 = new int [ 10 ] ( ) ;
delete [ ] p2;
return 0 ;
}
426 智能指针与动态数组
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
unique_ptr< int [ ] > up ( new int [ 10 ] ) ;
for ( int i= 0 ; i!= 10 ; ++ i) {
up[ i] = i;
}
for ( size_t i= 0 ; i!= 10 ; ++ i) {
cout << up[ i] << " " ;
}
cout << endl;
up. release ( ) ;
shared_ptr< int > sp ( new int [ 10 ] , [ ] ( int * p) { delete [ ] p; } ) ;
sp. reset ( new int [ 20 ] ) ;
for ( size_t i= 0 ; i!= 10 ; ++ i) {
* ( sp. get ( ) + i) = i;
}
for ( size_t i= 0 ; i!= 10 ; ++ i) {
cout << * ( sp. get ( ) + i) << " " ;
}
cout << endl;
return 0 ;
}
12.23
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
const char a[ ] = "aaa" ;
const char b[ ] = "bbb" ;
char * ans = new char [ strlen ( a) + strlen ( b) ] ;
strcpy ( ans, a) ;
strcat ( ans, b) ;
for ( size_t i= 0 ; i!= strlen ( ans) + 1 ; ++ i) {
cout << ans[ i] << " " ;
}
delete [ ] ans;
return 0 ;
}
12.24
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
const string a = "aaa" ;
const string b = "bbb" ;
string * ans = new string ( a + b) ;
for ( auto item: * ans) {
cout << item << " " ;
}
delete [ ] ans;
return 0 ;
}
12.24
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
char * ch = new char [ 3 ] ;
string s;
cin >> s;
strcpy ( ch, s. c_str ( ) ) ;
for ( size_t i= 0 ; i!= 3 ; ++ i) {
cout << ch[ i] << " " ;
}
cout << endl;
return 0 ;
}
427
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
size_t n = 5 ;
string * const p = new string[ n] ;
string s;
string * q = p;
while ( cin>> s && q != p + n) {
* q++ = s;
}
const size_t size = q - p;
cout << size << endl;
for ( size_t i = 0 ; i!= 6 ; ++ i) {
cout << p[ i] << " " ;
}
delete [ ] p;
return 0 ;
}
427 使用allocate类动态分配内存,对象构造
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
size_t n = 6 ;
allocator< string> alloc;
auto const p = alloc. allocate ( n) ;
auto q = p;
alloc. construct ( q++ , "hi" ) ;
cout << * p << endl;
while ( q!= p) {
alloc. destroy ( -- q) ;
}
alloc. deallocate ( p, n) ;
return 0 ;
}
429
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
vector< string> vi = { "a" , "b" , "c" } ;
allocator< vector< string>> alloc;
auto p = alloc. allocate ( vi. size ( ) * 2 ) ;
auto q = uninitialized_copy ( vi. begin ( ) , vi. end ( ) , p) ;
uninitialized_fill_n ( q, vi. size ( ) , 42 ) ;
return 0 ;
}
12.26
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <iterator>
# include <memory>
# include <fstream>
using namespace std;
int main ( ) {
allocator< string> alloc;
auto p = alloc. allocate ( 3 ) ;
string s;
auto q= p, r= p;
while ( cin>> s&& q!= p+ 3 ) {
alloc. construct ( q++ , s) ;
}
for ( size_t i= 0 ; i!= 3 ; ++ i) {
cout << * ( r++ ) << " " ;
}
cout << endl;
while ( q!= p) {
alloc. destroy ( -- q) ;
}
alloc. deallocate ( p, 3 ) ;
return 0 ;
}
430 文本查询程序的设计
# include <iostream>
# include <vector>
# include <string>
# include <list>
# include <set>
# include <iterator>
# include <memory>
# include <fstream>
# include <map>
# include <sstream>
using namespace std;
using line_no = vector< string> :: size_type;
class QueryResult {
friend ostream& print ( ostream& , const QueryResult& ) ;
public :
QueryResult ( string s,
shared_ptr< set< line_no>> p,
shared_ptr< vector< string>> f) : sought ( s) , lines ( p) , file ( f) { }
private :
string sought;
shared_ptr< set< line_no>> lines;
shared_ptr< vector< string>> file;
} ;
class TextQuery {
public :
TextQuery ( ifstream & ) ;
QueryResult query ( const string& ) const ;
private :
shared_ptr< vector< string>> file;
map< string, shared_ptr< set< line_no>> > wm;
} ;
TextQuery :: TextQuery ( ifstream & is) : file ( new vector< string> ) {
string text;
while ( getline ( is, text) ) {
file-> push_back ( text) ;
int n = file-> size ( ) - 1 ;
istringstream line ( text) ;
string word;
while ( line>> word) {
auto & lines = wm[ word] ;
if ( ! lines)
lines. reset ( new set< line_no> ) ;
lines-> insert ( n) ;
}
}
}
QueryResult TextQuery :: query ( const string & sought) const {
static shared_ptr< set< line_no>> nodata ( new set< line_no> ) ;
auto loc = wm. find ( sought) ;
if ( loc== wm. end ( ) ) {
return QueryResult ( sought, nodata, file) ;
} else {
return QueryResult ( sought, loc-> second, file) ;
}
}
string make_plural ( size_t num, const string& input, const string& suffix) {
return ( num > 1 ) ? input+ suffix: input;
}
ostream & print ( ostream & os, const QueryResult & qr) {
os << qr. sought << " occurs " << qr. lines-> size ( ) << " " << make_plural ( qr. lines-> size ( ) , "time" , "s" ) << endl;
for ( auto num: * qr. lines) {
os << "\t(line " << num+ 1 << ") " << * ( qr. file-> begin ( ) + num) << endl;
}
return os;
}
void runQueries ( ifstream & infile) {
TextQuery tq ( infile) ;
while ( true ) {
cout << "enter word to look for, or q to quit: " ;
string s;
if ( ! ( cin>> s) || s== "q" ) break ;
print ( cout, tq. query ( s) ) << endl;
}
}
int main ( ) {
ifstream in ( "input.txt" ) ;
runQueries ( in) ;
}