C++primer练习13.49-54

练习13.49

为你的String类添加一个移动构造函数和一个移动赋值运算符

String(String&& a):elements(std::move(a.elements)),first_free(std::move(a.first_free)),cap(std::move(a.cap)){
            a.free();
        }
        String& operator=(String&&a){
            if(this!=&a)
            {
                free();
                elements=std::move(a.elements);
                first_free=std::move(a.first_free);
                cap=std::move(a.cap);
            }
            return*this;
        }

练习13.50

在你的String类的移动操作中添加打印语句,观察避免拷贝情况

::在内存满了的时候push_back会调用移动构造函数

练习13.51

虽然unique_ptr不能拷贝,但我们编写过一个clone函数,它是以值方式返回一个unique_ptr。解释为什么合法能工作?

::有移动构造函数,但是没有拷贝构造函数,只能移动不能拷贝

练习13.52

详细解释第478页中的HasPtr对象的赋值发生了什么?特别是,一步一步描述hp,hp2以及HasPtr的赋值运算符中的参数rhs的值发生了什么变化

::hp=hp2这里hp2是左值,且调用赋值运算符,由于参数非引用则会进行拷贝构造,然后生成临时对象(分配了内存空间),调用swap,函数结束随之销毁

而hp=std::move(hp2);这里hp2是右值,则会调用移动构造临时参数,这样hp2就被销毁了,而临时对象在函数结束后销毁

练习13.53

从底层效率来看,HasPtr的赋值运算符并不理想,解释为什么?为HasPtr实现一个拷贝赋值运算符和一个移动赋值运算符,并比较你的新的移动赋值运算符中执行的操作和拷贝并交换版本中执行的操作

    HasPtr& operator=(const HasPtr&a){
        ps=    a.ps;
         cout<<"kb"<<endl;
        return *this;
        }
        HasPtr& operator=(HasPtr&&a)noexcept{
        ps=a.ps;
        a.ps=nullptr;
        cout<<"yd"<<endl;
        return *this;
        }

避免参数拷贝的多余开销

练习13.54

如果我们定义了移动赋值运算符,但未改变swap的拷贝交换运算符,会发生什么?

::存在二义性

[Error] ambiguous overload for 'operator=' (operand types are 'HasPtr' and 'std::remove_reference<HasPtr&>::type {aka HasPtr}')

 

posted @ 2022-08-16 16:42  yddl  阅读(57)  评论(0编辑  收藏  举报