当前位置: 首页 > article >正文

基础2:值类型与右值引用

1.函数返回

在讲解右值之前,要知道下面这个函数要进行几次拷贝以及为什么?

int get_x()
{
    int x = 20;
    return x;
}

int a=get_x();

答案:两次

# 第一次
int tmp=a;
# 第二次
int x=tmp;

2.左值与右值

🍏2.1 能取地址操作的就是左值

int gx = 10;
int get_gx()
{
    return gx;
}

int get_x()
{
    int x = 20;
    return x;
}

get_x();  //右值
get_gx(); //右值,因为返回值是一个tmp变量

延伸一下,对 x++ 取地址和 ++x 取地址哪个可以成功?

int* p=&x++; // 错误
// 后++等价于
/* 
int func(int &a) {
  int b=a;
  a=a+1;
  return b; 
}
*/

int *q=&++x; // 正确
// 前++等价于
/*
int func(int &a) {
  a=a+1;
  return a; 
}
*/

🍎 2.2 左值和右值的爱恨情仇

  • 左值引用不接受右值,所以只能用右值引用来接收, Type&&
int &y=-10;  // 错误
int &&y=-10; // 正确

int &a=get_x();  // 错误
int &&a=get_x(); // 正确
  • 如何将左值转换为右值
    • 移动语义:std::move 可以将左值转换为右值 
    • static_cast<type &&>(xxx)

3. 赋值操作只有拷贝这一种解法吗

  • 拷贝操作:我想与一名10年水平的码农一样强,那我应该学习10年
  • 引用操作:与它共享一份大脑
  • 移动操作
    • 这个10年的码农今年150岁了去世了,把它的大脑移植过来
    • 这位码农150岁,干净长生不老了,弄死后移植过来

🍐 例子

拷贝操作:

#include <iostream>
#include <string.h>
#include <string>

// copy from 【现代 C++ 语言核心特性解析】
class BigMemoryPool
{
public:
    static const int PoolSize = 4096;
    BigMemoryPool() : pool_(new char[PoolSize]) {}
    ~BigMemoryPool()
    {
        if (pool_ != nullptr)
        {
            delete[] pool_;
        }
    }
    BigMemoryPool(const BigMemoryPool &other) : pool_(new char[PoolSize])
    {
        std::cout << "copy" << std::endl;
        memcpy(pool_, other.pool_, PoolSize);
    }

private:
    char *pool_;
};

BigMemoryPool getPool()
{
    BigMemoryPool memoryPool;
    return memoryPool;
}


int main()
{
  BigMemoryPool bbb = getPool();
}

输出

copy
copy

 将上述代码加入移动构造函数(这个10年的码农今年150岁了去世了,把它的大脑移植过来)

class BigMemoryPool
{
public:
    static const int PoolSize = 4096;
    BigMemoryPool() : pool_(new char[PoolSize]) {}
    ~BigMemoryPool()
    {
        if (pool_ != nullptr)
        {
            delete[] pool_;
        }
    }
    BigMemoryPool(BigMemoryPool &&other)
    {
        std::cout << "move" << std::endl;
        pool_ = other.pool_;
        other.pool_ = nullptr;
    }
    BigMemoryPool(const BigMemoryPool &other) : pool_(new char[PoolSize])
    {
        std::cout << "copy" << std::endl;
        memcpy(pool_, other.pool_, PoolSize);
    }

private:
    char *pool_;
};

int main()
{
  BigMemoryPool bbb = getPool(); // 这个10年的码农今年150岁了去世了,把它的大脑移植过来
}

输出

move
move

这位码农150岁,干净长生不老了,弄死后移植过来

BigMemoryPool aaa;
BigMemoryPool ccc = std::move(aaa);

输出

move

4. Notes:

  •  纯右值也可以std::move
  • 类中未实现移动构造,std::move之后仍是拷贝
  • 右值引用仍是左值 
    int  x=10;
    int &&z=std::move(x);
    &z; // 左值
  • 右值绑定在左值上连移动构造都不会发生
    BigMemoryPool aaa;
    BigMemoryPool &&ccc = std::move(aaa);


http://www.kler.cn/a/444957.html

相关文章:

  • 【网络云计算】2024第51周-每日【2024/12/17】小测-理论-解析
  • 开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述
  • 【C语言】特殊指针汇总
  • CEF127 编译指南 MacOS 篇 - 编译 CEF(六)
  • 【ArcGIS Pro】水文水资源、水生态与水环境
  • 将java项目部署到linux
  • React和Three.js结合-React Three Fiber
  • 前端面经每日一题Day16
  • 华为ensp--BGP路径选择-AS_Path
  • 电力场景输电塔分割数据集labelme格式288张4类别
  • AI 在游戏领域的革命性技术
  • 人工智能 (AI) 模型的数据泄露问题
  • Serverless监控和调试、持续集成和持续部署
  • 小红书关键词搜索采集 | AI改写 | 无水印下载 | 多维表格 | 采集同步飞书
  • MySQL日期类型
  • 如何高效使用 Facebook Business Manager (商务管理平台)
  • AI开发:支持向量机(SVM)鸢尾花模型入门教程- Python 机器学习
  • linux cpu 管理
  • Unity Post请求发送fromdata数据content-type
  • 企业为何需要可视化数据分析系统
  • 迅为RK3576开发板接口丰富4G/5G、wifi6、多网口、NPU等
  • linux 根据名称 杀死linux 上某个jar进程或其他进程
  • rust与python互通
  • honle电源控制器维修UV灯高压电源EVG EPS200
  • 【C语言】一文讲通 和*
  • github快速查找已被删除的文件指令日志