C++ Primer(第5版) 练习 13.40
练习 13.40 为你的StrVec类添加一个构造函数,它接受一个Initializer_list参数。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
# include <iostream>
# include <memory>
# include <utility>
# include <initializer_list>
using namespace std; class StrVec { public : StrVec ( ) : elements ( nullptr ) , first_free ( nullptr ) , cap ( nullptr ) { } StrVec ( const StrVec & ) ; StrVec ( initializer_list< string> li) ; StrVec & operator = ( const StrVec & ) ; ~ StrVec ( ) ; void push_back ( const string & ) ; size_t size ( ) const { return first_free - elements; } size_t capacity ( ) const { return cap - elements; } string * begin ( ) const { return elements; } string * end ( ) const { return first_free; } void reserve ( size_t s) ; void resize ( size_t s) ; private : Static allocator< string> alloc; void chk_n_alloc ( ) { if ( size ( ) == capacity ( ) ) reallocate ( ) ; } pair< string* , string* > alloc_n_copy ( const string* , const string* ) ; void free ( ) ; void reallocate ( ) ; string * elements; string * first_free; string * cap;
} ; void StrVec :: push_back ( const string & s) { chk_n_alloc ( ) ; alloc. construct ( first_free++ , s) ;
} pair< string* , string* > StrVec :: alloc_n_copy ( const string * b, const string * e) { auto data = alloc. allocate ( e - b) ; return { data, uninitialized_copy ( b, e, data) } ;
} void StrVec: free ( ) { if ( elements) { for ( auto p = first_free; p != elements; ) { alloc. destroy ( -- p) ; } alloc. deallocate ( elements, cap - elements) ; }
} StrVec :: StrVec ( const StrVec & s) { auto newdata = alloc_n_copy ( s. begin ( ) , s. end ( ) ) ; elements = newdata. first; first_free = cap = newdata. second;
} StrVec :: ~ StrVec ( ) { free ( ) ; } StrVec & StrVec:: operator = ( const StrVec & rhs) { auto data = alloc_n_copy ( rhs. begin ( ) , rhs. end ( ) ) ; free ( ) ; elements = data. first; first_free = cap = data. second; return * this ;
} void StrVec :: reallocate ( ) { auto newcapacity = size ( ) ? 2 * size ( ) : 1 ; auto newdata = alloc. allocate ( newcapacity) ; auto dest = newdata; auto elem = elements; for ( size_t i = 0 ; i != size ( ) ; ++ i) { alloc. construct ( dest++ , move ( * elem++ ) ) ; } free ( ) ; elements = newdata; first_free = dest; cap = elements + newcapacity;
} void StrVec :: reserve ( size_t s) { if ( s <= size ( ) ) { return ; } auto newElem = alloc. allocate ( s) ; auto dest = newElem; auto elem = elements; for ( size_t i = 0 ; i != size ( ) ; ++ i) { alloc. construct ( dest++ , move ( * elem++ ) ) ; } free ( ) ; elements = newElem; cap = newElem + s; first_free = dest;
} void StrVec :: resize ( size_t s) { if ( s > capacity ( ) ) { return ; } if ( s < size ( ) ) { auto newFisrt = first_free; for ( size_t i = 0 ; i != size ( ) - s; ++ i) { alloc. destroy ( -- newFirst) ; } fisrt_free = newFirst; return ; } else if ( s == size ( ) ) { return ; } else { auto newFirst = first_free; for ( size_t i = 0 ; i != s - size ( ) ; ++ i) { alloc. construct ( newFirst++ , "" ) ; } first_free = newFirst; return ; }
}