栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

C++移动语义

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++移动语义

左值右值

左右值的概念
简单来讲,左值(lvalue: located value)就是可以拿到地址的值。右值就是不能拿到地址的值。
比如
int a = 10; a是左值,10是右值。
int a = func(); a是左值,func()是右值。
右值引用符号: &&

int&& ra = 10;	//ra是右值引用,但其本身是一个左值(因为可以拿到它的地址),10是右值

程序判断左右值:
判断类型是否是左右值:
c++自带的判断函数:

std::is_lvalue_reference	//左值引用
std::is_rvalue_reference	//右值引用

例子:

{
        cout << "is lvalue: " << endl;
        cout << "int:" << is_lvalue_reference::value << ", ";
        cout << "int&:" << is_lvalue_reference::value <<", ";
        cout << "int&&:" << is_lvalue_reference::value << ", ";
        cout << "int*:" << is_lvalue_reference::value << ". ";
        cout << "n";

        cout << "is rvalue: " << endl;
        cout << "int:" << is_rvalue_reference::value << ", ";
        cout << "int&:" << is_rvalue_reference::value <<", ";
        cout << "int&&:" << is_rvalue_reference::value << ", ";
        cout << "int*:" << is_rvalue_reference::value << ". ";
        cout << "n";
        int&& ra = 10;
        cout << "decltype(ra):" << is_rvalue_reference::value << endl;
    }

运行结果:

移动语义

C++std::move 函数。
定义:

template 
typename remove_reference::type&& move (T&& arg) noexcept;

作用:
返回一个arg的右值引用。
官方例子:

// move example
#include       // std::move
#include      // std::cout
#include        // std::vector
#include        // std::string

int main () {
  std::string foo = "foo-string";
  std::string bar = "bar-string";
  std::vector myvector;

  myvector.push_back (foo);                    // copies
  myvector.push_back (std::move(bar));         // moves

  std::cout << "myvector contains:";
  for (std::string& x:myvector) std::cout << ' ' << x;
  std::cout << 'n';
  cout << "foo: " << foo << endl;
  cout << "bar: "< 

第一次调用myvector.push_back复制了foo的值到vector(foo保持原来的值。第二次调用使用了move函数把bar的值移动到vector里面(bar失去了他的值)。
输出:

myvector contains: foo-string bar-string
foo: foo-string
bar: 
移动构造函数

移动构造函数的输入是右值,编译器会自动调用移动构造函数来减少不必要的深度拷贝,比如下面的例子,因为CatBorn函数里的cat即将析构,是一个右值,所以编译器调用移动构造函数,把cat的pweight资源拿过来用。

class Cat
{
public:
    Cat(int w = 1): pweight(new int(w)){
        cout << "cat normal constructor." <	//拷贝构造函数
        cout << "cat copy constructor." << endl;
    }
    Cat(Cat&& cat): pweight(cat.pweight){	//移动构造函数
        cat.pweight = nullptr;
        cout << "cat move constructor" << endl; 
    }
    void Cry(){
        cout << "cat cry: " << *pweight;
    }
private:
    int* pweight;
};

Cat CatBorn()
{
    Cat cat;
    return cat;
}

int main()
{
	CatBorn().Cry();
}

运行输出:
cat normal constructor.
cat move constructor
cat cry: 1

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1038103.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号