c++primer 13.45-13.58

2019-06-09  本文已影响0人  青吟乐

13.45
平时引用是左值引用,当时用&&的时候就是右值引用比如
左值引用:

int a = 2;
int &p = a;

右值引用:

int &&p = 3;
int &&q = p;

左值持久,右值短暂,左值具有持久的状态,右值要么是字面值常量,要么是在表达式求值的过程中创建的临时对象(没有其他用户进行绑定且要被销毁):使用右值引用的代码可以自由的接管所引用的对象的资源
13.46
f()返回值类型是int,属于使用f()后才有的临时变量,使用&&
&
&
&&
13.47

String::String(const String&s){
    std::cout<<"拷贝构造函数"<<std::endl;
    auto newStr = alloc_n_copy(s.elements,s.first_free);
    elements = newStr.first;
    first_free = newStr.second;
}

String& String::operator=(const String&a){
    std::cout<<"拷贝赋值运算符"<<std::endl;
    auto newc = alloc_n_copy(a.elements,a.first_free);
    free();
    elements = newc.first;
    first_free = newc.second;
    return *this;
}

13.48

提示我 image.png
不知道为啥申请不到空间,我再看看
#include <iostream>
#include"String.h"
#include<vector>
using namespace std;

int main()
{
    std::vector<String> vec;
    String s1("xxx");
    String s2 = s1;
    vec.push_back(s1);
    vec.push_back(s2);

    return 0;
}

13.49
Message类

//从本message移动Folder指针
void Message::move_Folders(Message *m){
    folders = std::move(m->folders);
    for(auto v:folders){
        v->remMsg(m);
        v->addMsg(this);
    }
    m->folders.clear();
}
//移动构造函数
Message::(Message &&m){
    contents = m.contents;
    move_Folders(&m);
}
//移动赋值运算符
Message& Message::operator=(Message &&rhs){
    if(this!=&rhs){
        remove_from_Folders();
        contents = std::move(rhs.contents);
        move_Folders(&rhs);
    }
    return *this;
}

StrVec类

//移动构造函数
StrVec::StrVec(StrVec &&s) noexcept:elements(s.elements),first_free(s.first_free),cap(s.cap){
    //另s进入这样的状态-----对其运行析构函数是安全的
    s.elements = s.first_free = s.cap = nullptr;
}
//移动赋值运算符
StrVec &StrVec::operator=(StrVec &&rhs) noexcept{
    //首先检测自身赋值
    if(this != &rhs){
        free();                                 //释放已有元素
        elements = rhs.elements;                //从rhs接管资源
        first_free = rhs.first_free;
        cap = rhs.cap;
        //将rhs置于可析构的状态
        rhs.elements = rhs.first_free = rhs.cap = nullptr;
    }
    return *this;
}

String类

//移动构造函数
String::String(String &&s) noexcept{
    std::cout<<"移动构造函数"<<std::endl;
    elements = s.elements;
    first_free = s.first_free;
    s.elements = s.first_free = nullptr;

}
//移动赋值运算符
String &String::operator=(String &&rhs) noexcept{
    std::cout<<"移动赋值运算符"<<std::endl;
    if(this!=&rhs){
        free();
        elements = rhs.elements;
        first_free = rhs.first_free;
        rhs.elements = rhs.first_free = nullptr;
    }
    return *this;
}

13.50
参考cpp答案

#include <iostream>
#include"String.h"
#include<vector>
using namespace std;

String R(){
std::vector<String> vec;
    String s1("s");//默认构造函数
    vec.push_back(s1);//拷贝构造函数
    return s1;//临时量,移动构造函数
}
int main()
{
    String s=R();//移动构造函数
    return 0;
}

13.51
这里使用了移动构造函数,因为new int(p)是一个产生临时变量的表达式,所以它是一个右值,所以这里可以使用移动构造函数
13.52
hp2是左值,实用拷贝构造函数
std::move(hp2);就是使用移动操作啦std::move(hp2);是右值,可以使用移动构造函数
13.53
缺少移动操作,书上版本

    //移动构造函数
    HasPtr(HasPtr &&p) noexcept{
        ps = p.ps;
        i = p.i;
        p.ps = 0;
    }
    //赋值运算符既算是移动赋值运算符也算是拷贝赋值运算符
    HasPtr& operator=(HasPtr rhs){
        swap(*this,rhs);
        return *this;
    }

13.54
C:\wook_tool\MyCppSpace\primer_13_3\main.cpp|12|error: ambiguous overload for 'operator=' (operand types are 'HasPtr' and 'std::remove_reference<HasPtr&>::type {aka HasPtr}')|
13.55

void StrVec::push_back(std::string &&s){
    chk_n_alloc();                      //确保有空间容纳新的元素
    alloc.construct(first_free++,std::move(s));    //在first_free指向的元素中构造s的副本
}

13.56
ret是左值对象,是一直调用当前的sort,递归
13.57
Foo(*this)只会产生临时对象,就会调用&&版本的sort
13.58

#include <vector>
#include <iostream>
#include <algorithm>

using std::vector; using std::sort;

class Foo
{
public:
    Foo sorted() && ;
    Foo sorted() const &;
private:
    vector<int> data;
};

Foo Foo::sorted() && {
    sort(data.begin(), data.end());
    std::cout << "&&" << std::endl; // debug
    return *this;
}

Foo Foo::sorted() const &
{
    //    Foo ret(*this);
    //    sort(ret.data.begin(), ret.data.end());
    //    return ret;

    std::cout << "const &" << std::endl; // debug

      //  Foo ret(*this);
      //  ret.sorted();     // Exercise 13.56
       // return ret;

    return Foo(*this).sorted(); // Exercise 13.57
}

int main()
{
    Foo().sorted(); // call "&&"
    Foo f;
    f.sorted(); // call "const &"
}
上一篇下一篇

猜你喜欢

热点阅读