Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >右值引用和构造

右值引用和构造

作者头像
changan
发布于 2020-12-21 01:36:44
发布于 2020-12-21 01:36:44
42700
代码可运行
举报
运行总次数:0
代码可运行

copy constructor/assign & move constructor/assign

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MClass
{
public:
    int* pIntdata;
    int sz;
public:
    MClass(int size) : sz(size)
    {
        pIntdata = new int[size];
        for(int i=0;i<sz;i++)
        {
            pIntdata[i] = i;
        }
        std::cout<< "constructor|addr:" << this << std::endl;
    }
    
    MClass& operator=(const MClass& h)
    {
        std::cout<< "copy assign  operator= " << std::endl;
        this->sz = h.sz;
        if(  this->pIntdata ){ delete [] this->pIntdata ; this->pIntdata = NULL; } // instance get own ptr, size maybe change, del previous
        
        pIntdata = new int[sz];
        for(int i=0;i<sz;i++)
        {
            pIntdata[i] = h.pIntdata[i];
        }   
        return *this;
    }
    
    MClass(const MClass &h) : sz(h.sz ) // copy constructor must pass its first argument by reference 
    {
        this->sz = h.sz; 
        pIntdata = new int[sz];
        for(int i=0;i<sz;i++)
        {
            pIntdata[i] = h.pIntdata[i];
        }
        std::cout<< "copy constructor " << this << std::endl;
    }
    
    MClass( MClass && h ): sz(h.sz ),pIntdata(h.pIntdata)  // move constructor 
    {
        std::cout<< "move constructor " << this << std::endl;
        h.pIntdata = nullptr;               // 处理关联的资源
    }
    MClass& operator=( MClass&& h)
    {
        std::cout<< "move MClass& operator=(const MClass&&) " << this << std::endl;
        this->sz = h.sz;
        this->pIntdata = h.pIntdata;

        h.pIntdata = nullptr;
    }
    ~MClass()
    {
        if( pIntdata  )
        {
            delete [] pIntdata;
            pIntdata = NULL;
        } 
        std::cout<< "destructor " << this << std::endl;
    }
};

MClass GetOne()
{
    MClass mc = MClass(42);
    std::cout << "GetOne()::&mc " <<  &mc  << std::endl;
    return mc; 
}

int func(MClass&& mc)
{
    std::cout << "int func(MClass&& mc)|&mc:" << &mc << std::endl;
    return 0; 
}

int func2(MClass mc)
{   
    std::cout << "int func1(MClass&& mc)|&mc:" << &mc << std::endl;
    return 0;
}

int main()
{
    MClass one = GetOne();  // -fno-elide-constructors 编译器优化
    std::cout << "main::&one " <<  &one  << std::endl;
    MClass two = func( std::move(one) );

    MClass t3(5);
    t3 = std::move(one);
    return 0;
}

C++ 的移动 move 是怎么运作的?

引入移动构造是为了避免多余的堆申请

std::move在运行期不做任何事情(不生成任何机器码),在编译期只做一件事情,就是把入参cast成对应类型的rvalue,从而影响其他函数调用的重载决议。你可以理解成std::move其实应该叫做比如说cast_to_rvalue,但是标准委员会认为这个破名字太长不好记。搞清楚这点你就理解了std::move了。

C++ 的移动 move 是怎么运作的? C++的move基本啥也没干, 逻辑是自己实现的,参考上面的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MClass( MClass && h ): sz(h.sz ),pIntdata(h.pIntdata)  // move constructor 
{
    std::cout<< "move constructor " << this << std::endl;
    h.pIntdata = nullptr;             
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
理解 C++ 右值引用和 std::move
上述涉及到的移动语义,是由C++11之前存在的一些历史遗留问题,使C++标准库的实现在多种场景下消除了不必要的额外开销(如std::vector, std::string).这些问题都由于构造函数和拷贝构造函数以及赋值构造函数引起.
Rock_Lee
2021/08/27
8770
C++11移动语义与右值引用
C++11新标准中一个最主要的特性就是提供了移动而非拷贝对象的能力。如此做的好处就是,在某些情况下,对象拷贝后就立即被销毁了,此时如果移动而非拷贝对象会大幅提升性能。参考如下程序:
恋喵大鲤鱼
2019/02/22
1.1K0
【C++11】{}/右值引用/移动语义/类型分类/引用折叠/完美转发--C++
C++11 是 C++ 的第二个主要版本,并且是从 C++98 起的最重要更新。它引入了大量更改,标准化了既有实践,并改进了对 C++ 程序员可用的抽象。在它最终由 ISO 在 2011 年 8 月 12 日采纳前,人们曾使用名称“C++0x”,因为它曾被期待在 2010 年之前发布。C++03 与 C++11 期间花了 8 年时间,故而这是迄今为止最长的版本间隔。从那时起,C++ 有规律地每 3 年更新一次。
小志biubiu
2025/02/27
1160
【C++11】{}/右值引用/移动语义/类型分类/引用折叠/完美转发--C++
现代 C++:右值引用、移动语意、完美转发
右值引用(rvalue reference)是 C++11 为了实现移动语意(move semantic)和完美转发(perfect forwarding)而提出来的。
linjinhe
2020/06/02
2.6K0
C++11——对象移动与右值引用
C++11新标准中一个最主要的特性就是提供了移动而非拷贝对象的能力。如此做的好处就是,在某些情况下,对象拷贝后就立即被销毁了,此时如果移动而非拷贝对象会大幅提升性能。参考如下程序:
恋喵大鲤鱼
2018/08/03
9130
C++11特性:初始化列表、右值引用、可变模板
C++11 是 C++ 的第⼆个主要版本,并且是从 C++98 起的最重要更新。它引⼊了⼤量更改,标准化了既 有实践,并改进了对 C++ 程序员可⽤的抽象。在它最终由 ISO 在 2011 年 8 ⽉ 12 ⽇采纳前,⼈们曾使 ⽤名称“C++0x”,因为它曾被期待在 2010 年之前发布。C++03 与 C++11 期间花了 8 年时间,故⽽这 是迄今为⽌最⻓的版本间隔。从那时起,C++ 有规律地每 3 年更新⼀次。
用户11375356
2025/02/11
1450
C++11特性:初始化列表、右值引用、可变模板
【专业技术】从4行代码看右值引用
概述   右值引用的概念有些读者可能会感到陌生,其实他和C++98/03中的左值引用有些类似,例如,c++98/03中的左值引用是这样的: int i = 0;int& j = i;   这里的int&是对左值进行绑定(但是int&却不能绑定右值),相应的,对右值进行绑定的引用就是右值引用,他的语法是这样的A&&,通过双引号来表示绑定类型为A的右值。通过&&我们就可以很方便的绑定右值了,比如我们可以这样绑定一个右值: int&& i = 0;   这里我们绑定了一个右值0,关于右值的概念会在后面介绍。右值引
程序员互动联盟
2018/03/16
1.6K0
【专业技术】从4行代码看右值引用
C++按值返回对象那些事
某年某月的某一天,组里新来了一个工作多年的专家工程师。领导让其在我当前负责的模块上做一些优化工作。很快专家提出来很多C++语法上的修改意见。比如:
果冻虾仁
2021/12/08
8520
深入解析C++右值引用和移动语义:编写更快、更节省内存的代码
a可以通过&取地址,位于等号左边,所以a是左值。10位于等号右边且无法通过&取地址,所以10是右值。
Lion 莱恩呀
2024/11/09
2800
深入解析C++右值引用和移动语义:编写更快、更节省内存的代码
【c++11】右值引用和移动语义
传统的C++语法中就有引用的语法,而C++11中新增了的右值引用语法特性,所以从现在开始我们之前学习的引用就叫做左值引用。无论左值引用还是右值引用,都是给对象取别名
用户11029103
2025/01/20
1890
【c++11】右值引用和移动语义
【重学C++】04 | 说透C++右值引用(上)
大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第四讲,在前面《03 | 手撸C++智能指针实战教程》中,我们或多或少接触了右值引用和移动的一些用法。
会玩code
2023/07/08
2190
【重学C++】04 | 说透C++右值引用(上)
蓝桥ROS机器人之现代C++学习笔记3.3 右值引用
右值引用和左值引用 #include <iostream> #include <string> void reference(std::string& str) { std::cout << "lvalue" << std::endl; } void reference(std::string&& str) { std::cout << "rvalue" << std::endl; } int main() { std::string lv1 = "string,";
zhangrelay
2022/04/29
2540
蓝桥ROS机器人之现代C++学习笔记3.3 右值引用
深入理解 C++ 标准中的右值引用
C++ 是一门极为复杂且灵活的编程语言,而右值引用(rvalue reference)是 C++11 标准中引入的一项重要特性。它不仅扩展了语言的语法,还提供了全新的编程思路,对资源管理和性能优化起到了巨大的推动作用。
编程小妖女
2025/01/15
1290
C++11第二弹:左右值 | 左右值引用 | 移动构造 | 完美转发
什么是左值?什么是左值引用? 左值是一个表示数据的表达式(如变量名或解引用的指针),我们**可以获取它的地址并且可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。**定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。
南桥
2024/09/09
1410
C++11第二弹:左右值 | 左右值引用 | 移动构造 | 完美转发
[C++11] 右值引⽤与移动语义
在C++中,左值(lvalue)和右值(rvalue)是两种不同的表达式类型,它们的主要区别在于它们在内存中的状态和使用方式。
DevKevin
2024/10/28
1750
[C++11] 右值引⽤与移动语义
C++的右值引用&&
C++11 引入了右值引用(Rvalue References)的概念,它是一种新的引用类型,与传统的左值引用(Lvalue References)相对应。右值引用主要用于支持移动语义和完美转发。
叶茂林
2023/07/30
3620
左右值引用和移动语义
什么是左值、右值呢?一种极不严谨的理解为:在赋值的时候,能够被放到等号左边的值为左值,放在右边的值为右值。例如:
艰默
2023/02/26
9310
左右值引用和移动语义
深入理解C++11右值引用与移动语义:高效编程的基石
在现代C++编程中,性能优化和资源管理一直是开发者追求的目标。C++11引入的右值引用(rvalue reference)和移动语义(move semantics)为解决这些问题提供了强有力的工具。通过右值引用,我们能够更高效地处理临时对象;而移动语义的引入,则进一步优化了对象的资源转移和管理。在这篇文章中,我们将深入探索右值引用和移动语义的核心概念、实现原理,以及它们在实际开发中的应用场景。
suye
2024/11/21
1670
深入理解C++11右值引用与移动语义:高效编程的基石
C++ 08 - copy elision
当用一个临时对象初始化另一个对象的时候, 如果他们两个的 cv-unqualified type 相同, 并且临时对象没有和任何引用绑定, 那么此次 copy/move construction 是可以省略的:
Reck Zhang
2021/08/11
3330
C++11新特性概览
今天买的《C++ Primer 第五版》到了,这一版本一个比较好的地方是。在开始的目录里面列出来了全书中涉及到的C++11新特性的地方,标明了页码,可以直接到对应的页面去看新特性的东西。于是我对照书上的例子,写了一些简单的示例,用来大概的了解C++11的新特性,总结在这里,以后可以查查。
王云峰
2019/12/25
4510
相关推荐
理解 C++ 右值引用和 std::move
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验