编写StrVec中遇到的问题总结
错误提示1:undefined reference to `StrVec::alloc[abi:cxx11]'
类的静态数据成员需要在类外定义。
解决方式在类外加上代码:
allocator<string> StrVec::alloc;
错误提示2:error: passing 'const StrVec' as 'this' argument discards qualifiers [-fpermissive]
在类中,const修饰的对象只能访问该对象中的const成员函数,如果访问非const成员函数可能会对实参进行修改,所以报错。
解决方式:1.在被调用函数的形参列表后加const,把调用的成员函数变成const成员函数
2.不用const修饰该对象。
#include <iostream> using namespace std; struct Base { Base(){ cout<<"Base::Base()"<<endl; } void test() {//出错 //void test() const{//解决方式1 cout<<"test in base"<<endl; } }; void MyTest( const Base &b) //void MyTest( Base &b)//解决方式2 { b.test(); } int main(int argc, char *argv[]) { Base b; MyTest(b); return 0; }
//StrVec
#include <iostream> #include <memory> #include <string> //仅支持string类型的vector //使用alloc来分配内存, //成员:静态成员alloc,用来分配内存 //用来指示元素位置的指针,共三个, //elements表示vec的起始位置 //first_free表示第一个空的位置,可以插入元素 //cap表示申请的连续内存的尾后位置 using namespace std; class StrVec { static allocator<string> alloc; private: string *elements;//首元素的位置 string *first_free;//第一个空闲的位置 string *cap;//连续内存尾后的位置 public: StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}//构造函数 size_t size(){return first_free-elements;} size_t capacity(){ return cap-elements; } void check_capacity(); pair<string*,string*> copy_n_string(string*,string*); void reallocate(); void push_back(const string&); void Free(); string* begin(){ return elements; } string* end(){ return first_free; } StrVec( StrVec&); StrVec& operator=( StrVec&); ~StrVec(){ Free(); } } ; allocator<string> StrVec::alloc;//静态数据成员需要在类外定义 void StrVec::Free() { if(elements) { for(string* p=elements;p!=first_free;++p) { alloc.destroy(p);//析构元素 } alloc.deallocate(elements,cap-elements);//释放内存 } } void StrVec::push_back(const string& s) { check_capacity();//插入前检查容器是否已满 alloc.construct(first_free++,s); } pair<string*,string*> StrVec::copy_n_string(string* b,string* e) { //string* temp=dest; //for(string* p=beg;p!=end;++p) //{ //alloc.construct(dest++,*p++) //} /*free(); elements=temp; first_free=dest; cap=elements + this->size();*/ string* data=alloc.allocate(e-b);//需要分配的内存空间 return {data,uninitialized_copy(b,e,data)}; } void StrVec::reallocate() { size_t oldsize=this->size(); size_t newsize=(oldsize)?(2*oldsize):1;//得到要分配的内存大小 string* dest=alloc.allocate(newsize);//返回分配内存的起始位置 string* b=dest; string* elem=elements;//旧数组中的下一位置 for(size_t i=0;i<oldsize;++i) { alloc.construct(b++,std::move(*elem++));//旧数组中的元素搬到新数组中 } //释放旧数组内存 Free(); elements=dest;//新的首元素位置 first_free=b;//第一个空闲元素位置 cap= elements+newsize; } void StrVec::check_capacity() { if(first_free == cap) { reallocate(); //copy_n_string();// } } StrVec::StrVec( StrVec& rhs) { auto temp=copy_n_string(rhs.begin(),rhs.end());//临时保存右边的数据 //free();本来没有,所以不需要清除 elements=temp.first; cap=first_free=temp.second;//容量和元素个数都相同 } StrVec& StrVec::operator=( StrVec& rhs) { auto temp=copy_n_string(rhs.begin(),rhs.end()); Free();//清除旧数组内存 elements=temp.first; cap=first_free=temp.second; return *this; } int main(int argc, char *argv[]) { string s1("asd"),s2("qwe"); StrVec st; st.push_back(s1); st.push_back(s2); cout<<*st.begin()<<endl; cout<<*(st.begin()+1)<<endl; return 0; }