C++ Primer(第5版) 练习 12.20
练习 12.20 编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob中的每个元素。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
# include <iostream>
# include <fstream>
# include <sstream>
# include <string>
# include <vector>
# include <memory>
using namespace std;
class StrBlobPtr ;
class StrBlob {
friend class StrBlobPtr ;
public :
typedef vector< string> :: size_type size_type;
StrBlob ( ) : data ( make_shared < vector< string>> ( ) ) { }
StrBlob ( initializer_list< string> il) : data ( make_shared < vector< string>> ( il) ) { }
size_type size ( ) const { return data-> size ( ) ; }
bool empty ( ) const { return data-> empty ( ) ; }
void push_back ( const string & t) { data-> push_back ( t) ; }
void pop_back ( ) ;
string & front ( ) ;
string & back ( ) ;
string & front ( ) const ;
string & back ( ) const ;
StrBlobPtr begin ( ) ;
StrBlobPtr end ( ) ;
private :
shared_ptr< vector< string>> data;
void check ( size_type i, const string & msg) const ;
} ;
void StrBlob :: pop_back ( ) {
check ( 0 , "pop_back on empty StrBlob" ) ;
data-> pop_back ( ) ;
}
string& StrBlob :: front ( ) {
check ( 0 , "front on empty StrBlob" ) ;
return data-> front ( ) ;
}
string& StrBlob :: back ( ) {
check ( 0 , "back on empty StrBlob" ) ;
return data-> back ( ) ;
}
string& StrBlob :: front ( ) const {
check ( 0 , "front on empty StrBlob" ) ;
return data-> front ( ) ;
}
string& StrBlob :: back ( ) const {
check ( 0 , "back on empty StrBlob" ) ;
return data-> back ( ) ;
}
void StrBlob :: check ( size_type i, const string & msg) const {
if ( i >= data-> size ( ) ) {
throw out_of_range ( msg) ;
}
}
class StrBlobPtr {
friend bool compare ( StrBlobPtr & a, const StrBlobPtr & b) ;
public :
StrBlobPtr ( ) : curr ( 0 ) { }
StrBlobPtr ( StrBlob & s, size_t sz = 0 ) : wptr ( s. 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 ( ) ) ;
}
bool compare ( StrBlobPtr & a, const StrBlobPtr & b) {
if ( a. wptr. lock ( ) == b. wptr. lock ( ) && a. curr == b. curr) {
return true ;
}
return false ;
}
int main ( ) {
ifstream in ( "12.20.txt" ) ;
StrBlob file;
string str;
StrBlobPtr nFile ( file) ;
while ( getline ( in, str) ) {
file. push_back ( str) ;
}
for ( auto it = file. begin ( ) ; ! compare ( it, file. end ( ) ) ; it. incr ( ) ) {
cout<< it. deref ( ) << " " ;
}
cout<< endl;
in. close ( ) ;
return 0 ;
}
运行结果显示如下