首页 > 编程语言 >c++移动构造函数

c++移动构造函数

时间:2023-03-09 13:44:16浏览次数:44  
标签:构造函数 对象 xptr c++ 复制 移动 指针

一.介绍

1.1 定义【源对象资源的控制权全部移交给目标对象

有些复制构造是必要的,我们确实需要另外一个副本;而有些复制构造是不必要的,我们可能只是希望这个对象换个地方,移动一下而已。在C++11之前,如果要将源对象的状态转移到目标对象只能通过复制。而现在在某些情况下,我们没有必要复制对象——只需要移动它们。移动构造是C++11标准中提供的一种新的构造方法,移动构造可以减少不必要的复制,带来性能上的提升

C++11引入移动语义:~源对象资源的控制权全部交给目标对象 

移动构造函数定义形式:

class_name(class_name && ) //右值引用传参

移动构造函数中的参数类型,&&符号表示是右值引用;即将消亡的值就是右值,函数返回的临时变量也是右值,这样的单个的这样的引用可以绑定到左值的,而这个引用它可以绑定到即将消亡的对象,绑定到右值。

1.2 拷贝构造与移动构造

  • 复制构造:在对象被复制后临时对象和复制构造的对象独自都占有不同地址的堆内存就是一个副本【深拷贝】
  • 移动构造:是让这个临时对象它原本控制的内存的空间转移给构造出来的对象,这样就相当于把它移动过去了

 

 

 

 

 

这种情况下,我们觉得这个临时对象完成了复制构造后,就不需要它了,我们就没有必要去首先产生一个副本,然后析构这个临时对象,这样费两遍事,又占用内存空间,所幸将临时对象它的原本的资源直接转给构造的对象即可了。当临时对象在被复制后,就不再被利用了,我们完全可以把临时对象的资源直接移动,这样就避免了多余的复制构造

1.3 移动构造使用场景【对象返回值传递,将亡对象

如果临时对象即将消亡,并且它里面的资源是需要被再利用的,这个时候我们就可以触发移动构造。

#include<iostream>    
using namespace std;    
class IntNum{    
public:  
     //构造函数      
     IntNum(int x = 0):xptr(new int(x))
    {
       cout<<"Calling constructor..."<<endl;    
    }  
    //复制构造函数      
    IntNum(const IntNum &n):xptr(new int(*n.xpr))
    {
         cout<<"Calling copy constructor..."<<endl;    
    } 
    //移动构造函数    
   IntNum(IntNum && n):xptr(n.xptr)
    {
         n.xptr = nullptr;  
         cout<<"Calling move constructor..."<<endl;  
    }  
    //析构函数    
       ~IntNum()
    {
        delete xpr;    
        cout<<"Destructing..."<<endl;  
    }   
        int getInt(){return *ptr;}//返回指针所指向的值,而不是返回指针本身    
private:    
         int *ptr;    
};    
    
//返回值为IntNum类对象 ,将亡值
IntNum getNum(){    
     //定义了一个局部对象,然后将局部对象作为结果返回    
      IntNum a;       
      return a;    
}    
  int main(){    
   //getNum()函数返回了一个IntNum类型的对象(临时无名对象),之后调用类的函数    
    cout<<"getNum().getInt()"<<endl;    
    return 0;    
}        

在该例中的移动构造函数:好像干了件很危险的事情:直接用参数对象(n)里面的指针(n.xptr)来初始化当前对象的指针(xptr),(按理说这不是浅层复制吗?!说了有指针成员,我们复制时不能做这种浅层复制的呀,怎么在这里我们恰恰做浅层复制了呢)

IntNum(IntNum && n):xptr(n.xptr){//移动构造函数
     n.xptr = nullptr;
     cout<<"Calling move constructor..."<<endl;
}

看函数体里面,我们发现再做完xptr(n.xptr)这种指针对指针的复制(也就是把参数指针所指向的对象转给了当前正在被构造的指针)后,接着就把参数n里面的指针置为空指针(n.xptr = nullptr;)对象里面的指针置为空指针后,将来析构函数析构该指针(delete xpr;)时,是delete一个空指针,不发生任何事情,这就是一个移动构造函数

 

 

原文:

https://blog.csdn.net/sinat_25394043/article/details/78728504?ops_request_misc=&request_id=&biz_id=102&utm_term=%E7%A7%BB%E5%8A%A8%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-78728504.nonecase&spm=1018.2226.3001.4187

标签:构造函数,对象,xptr,c++,复制,移动,指针
From: https://www.cnblogs.com/david-china/p/17198052.html

相关文章

  • c++ 性能分析
    本文记录下日常工作中用到的性能分析工具。一、内存泄漏排查我的服务依赖了jemalloc,这个地方记录下使用jemalloc进行内存分析的方法。1编译jemalloc首先,依赖的je......
  • 从一个坐标点移动到另一个坐标点,每次移动x,y最大举例不能超过127 , 算法
    我的思路是这样的,先移正方形距离,再移横向或者纵向距离,最终移动边边角角的距离代码如下typeKVMMouseControlstruct{ KeyStateuint8`json:"keyState"`//按键状态......
  • 【C++】购书系统问题测试&功能补充
    代码来源:舍友大一的C++作业【代码存在的问题】在菜单界面选择对应序号时,若输入值非数字,而是字母等其它符号,会导致程序陷入循环,无法正常进入功能的下一步     ......
  • [Primer] 第 14 章 C++ 中的代码重用
    第14章C++中的代码重用14.1包含对象成员的类类初始化列表中有多个项目时,初始化的顺序为在类中的声明顺序而不是列表顺序。14.2私有继承使用私有继承,基类的所有公......
  • gcc 编译 C/C++ 文件
    gcc编译C/C++文件众所周知,C/C++程序想要得到执行,主要需要执行编译和链接两个过程,这个过程比较繁琐,尤其是程序使用到了其他的头文件的时候。gcc是常用的编译工具,其流程主要......
  • (P01)C++介绍
    文章目录​​1.需要掌握的重要练习​​​​2.为什么要学习C++​​​​3.C++为什么难学​​​​4.C++11值得学习的新特性​​​​5.几本推荐学习C++的书​​​​6.开发工具......
  • (P03)从C到C++:域运算符,new,delet运算符,重载,name managling与extern “C“,带默认参数的函
    文章目录​​1.域运算符​​​​2.new、delete运算符​​​​3.重载​​​​4.namemanagling与extern“C”​​​​5.带默认形参值的函数​​​​6.带默认形参值的函数的......
  • (P05)从C到C++:内联函数,带参数宏,4种强制类型转化
    文章目录​​1.内联函数​​​​2.4种新的类型转换运算符​​1.内联函数当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系......
  • ES6-ES11 ES5构造函数继承
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>对象继......
  • C/C++校园核酸检测管理程序[2023-03-08]
    C/C++校园核酸检测管理程序[2023-03-08]2022级课程设计1(程序设计语言C)参考题目及需求说明题目:校园核酸检测管理程序1程序使用人员采集员、检测员、待检者。为了......