C++primer练习13.41-48


练习13.41

在push_back中我们为什么在construct调用后置递增

::因为first_free指针就是第一个空闲位置,使用前置每次插入都会隔一个位置

练习13.42

在你的textQuery和Queryresult类中用strvec代替vector<string>进行测试

::用StrVec替换vector<string>测试即可

练习13.43

重写free成员,用for_each和lambda来代替for循环destroy元素,你倾向于哪个?

::倾向于for_each,更好看

inline
void StrVec::free()
{
    
    if (elements) {
    
        for_each (elements,first_free,alloc.destroy )
         
        alloc.deallocate(elements, cap - elements);
    }
}
    

练习13.44

编写标准库string类的简化版本,命名为String。你的类应该至少有一个默认构造函数和一个接受c风格的字符串指针参数的构造函数,使用allocator为你的String类分配所需内存

#include <memory>
#include <memory>
using namespace std;
class String{
    
    public:
        String():elements(nullptr),first_free(nullptr),cap(nullptr){        }
        String(const String& s){
            auto data=alloc_ncopy(s.begin(),s.end());
                elements=data.first;
            first_free=cap=data.second;
        }
        String& operator=(const String&s){
            auto data=alloc_ncopy(s.begin(),s.end());
            free();
            elements=data.first;
            first_free=cap=data.second;}
        
        
        ~String(){free();}
        String(const char*a,const char*b)
        {
            auto data=alloc_ncopy(a,b);
            elements=data.first;
            first_free=cap=data.second;
        }
        void push_back(char&c){check();alloc.construct(first_free++,c);        }
        size_t size()const{return first_free-elements;}
        size_t capacity(){return cap-elements;        }
        char* begin()const{return elements;        }
        char* end()const{return first_free;        }
        
    private:
        static allocator<char> alloc;
        char* elements;
        char* first_free;
        char* cap;
        void check(){if(size()==capacity())reallocate();}
        pair<char*,char*> alloc_ncopy(const char*a,const char*b){
            auto data=alloc.allocate(b-a);
            return {data,uninitialized_copy(a,b,data)};
        }
         void reallocate()
         {
             size_t newcapacity = size() ? 2 * size() : 1;
             char* newdata =alloc.allocate(newcapacity);
             char*dest=newdata;
             char*elem = elements;
             for (size_t i = 0; i != size(); ++i)
                alloc.construct(dest++, *elem++);
            free();
            elements=newdata;
            first_free = dest;
            cap = elements + newcapacity;
         }
        void free()
        {
               if (elements) {
        
                for (char*p = first_free; p != elements; )
                    alloc.destroy(--p);  
            alloc.deallocate(elements, cap - elements);
                            }
        }
        
};
allocator<char> String::alloc;

练习13.45

解释右值引用和左值引用的区别

::可以这样理解右值是值,左值是地址,所以分别是对值的引用和对地址的引用,不过右值引用和左值引用都是左值

练习13.46

什么类型的引用可以绑定到下面的初始化器上?

int f();

vector<int> vi(100);

int&& r1=f();

int& r2=vi[0];

int& r3=r1;

int&& r4=vi[0]*f();

练习13.47

对你在练习13.44中定义的String类,为它的拷贝构造函数和拷贝赋值运算符添加一条语句,打印一条信息

    String(const String& s){
            auto data=alloc_ncopy(s.begin(),s.end());
                elements=data.first;
            first_free=cap=data.second;
            cout<<"拷贝构造"<<endl;
        }
        String& operator=(const String&s){
            auto data=alloc_ncopy(s.begin(),s.end());
            free();
            elements=data.first;
            first_free=cap=data.second;
            cout<<"赋值运算"<<endl;}

练习13.48

定义一个vector<String>并在其上多次调用push_back,观察拷贝构造调用次数。

::每当vector内存满了要push_back,就会重新分配等于自身两倍的内存,并将已有的元素拷贝过去。

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/280893.html

(0)
上一篇 2022年8月16日
下一篇 2022年8月16日

相关推荐

发表回复

登录后才能评论