编写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;
}

 

posted @ 2022-03-25 14:38  菠萝超级酸  阅读(234)  评论(0编辑  收藏  举报