设为首页 加入收藏

TOP

右值引用和移动语义(一)
2019-07-08 12:10:08 】 浏览:30
Tags:引用 移动 语义

前言

因为工作室要求写技术博客记录学习到的知识点,自己之前是没有写过博客的,所以现在用一篇介绍右值引用和移动语义的博客作为博客的第一篇,可能对于移动语义的理解还不够深刻,但可以作为一个简单的介绍博客

右值引用

要理解好右值引用首先要知道什么是左值?什么是右值?

1.左值是表达式结束后依然存在的持久化对象
2.右值则是表达式结束时就不再存在的值

便捷区别方法:对表达式取地址,如果能,是左值,否则是右值

int a=10; 
int b=5; //这是一个左值
&(a+b);    //这是一个右值

//区别方法
&a       //因为a是个左值,可以对其取地址
&(a+b)  //因为(a+b)是个临时变量,是右值,并不能对其取地址

下面先来对左值引用作一些介绍

由于修饰符不同可以分为非常量左值和常量左值

1.==非常量左值只能绑定左值==
2.常量左值是个奇葩,因为他不仅可以绑定左值(非常量和常量),也能够绑定右值
为什么它能够绑定右值呢?
在于他们绑定了右值后,延长了右值的生命周期,使之像一个左值一样,但有一个东西是只能读不能改
int a=10;       
int c=10;//非常量左值
const int b=5;  //常量左值

int& d=a; //可以
int& d=a+c; //报错 a+b是右值
int& d=b;   //报错 b是常量左值

const int& e=a;
const int& e=b;
const int& e=a+c; 
//上面的三条式子都不会报错,因为常量左值都可以绑定

在c++11中添加了右值引用的概念,用&&来表示右值引用


说梢酝ü抑狄檬蛊浔淮娲⒌教囟ǖ奈恢们铱梢曰竦酶梦恢玫牡刂">原本右值是个临时变量,表达式结束时其生命也就结束了,但可以通过右值引用使其被存储到特定的位置,且可以获得该位置的地址

换句说:左值引用可以比作一个拥有姓名的人给其取个别名,而右值引用则是一个没有姓名的人然后给其取个别名

int a=10;
int b=10;
int&& c=a+b; //一个简单的右值引用

为什么要引入右值引用呢?目的之一则是下面要讲到的移动语义的实现

移动语义是实际文件还留在原来的地方,而只修改记录.

用下面一个Useless类来说明(具体实现就不说了)

#ifndef __USELESS_H
#define __USELESS_H

#include<iostream>

class Useless
{
public:
    Useless();
    Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless& f);  //复制构造函数
    Useless(Useless&& f);       //移动构造函数
    ~Useless(); 
    Useless operator+(const Useless& f) const;
    void ShowData() const;
private:
    int n; 
    char* pc;
    static int ct;
    void ShowObject() const;
};


#endif // __USELESS_H
#include "Useless.h"

int Useless::ct = 0;
Useless::Useless()
{
    ++ct;
    n = 0;
    pc = nullptr;
    std::cout << "default construct called;number of object: " << ct << std::endl;
    ShowObject();
}

Useless::Useless(int k): n(k)
{
    ++ct;
    std::cout << "int construct called;number of objects: " << ct << std::endl;
    pc = new char[n];
    ShowObject();
}

Useless::Useless(int k, char ch):n(k)
{
    ++ct;
    std::cout << "int char construct called;number of objects: " << ct << std::endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = ch;
    ShowObject();
}

Useless::Useless(const Useless & f):n(f.n)
{
    ++ct;
    std::cout << "copy const called;number of objects: " << ct << std::endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = f.pc[i];
    ShowObject();
}

Useless::Useless(Useless && f):n(f.n)
{
    ++ct;
    std::cout << " move construct called;number of objects: " << ct << std::endl;
    pc = f.pc;
    f.pc = nullptr; //give old object nothing in return 
    f.n = 0;
    ShowObject();
}

Useless::~Useless()
{
    std::cout << "destructor called;number of objects: " << --ct << std::endl;
    std::cout << "deleted object:\n";
    ShowObject();
    delete[] pc;
}

Useless Useless::operator+(const Useless & f) const
{
    std::cout << "Entering operator+()\n";
    Useless temp = Useless(n + f.n);
    for (int i = 0; i < n; i++)
        temp.pc[i] = pc[i];
    for (int i = n; i < temp.n; i++)
        temp.pc[i] = f.pc[i - n];
    std::cout << "temp object:\n";
    std::cout << "Leaving operator+()\n";
    return temp;
}

void Useless::ShowData() const
{
    if (n==0)
    {
        std::cout << "(object empty)";
    }
    else
    {
        for (int i = 0; i < n; i++)
            std::cout << pc[i];
    }
    std::co
			
		  
编程开发网
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇DFS和BFS的比较 下一篇BFS(二):数的变换

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }