首页 > 编程语言 >C++温故补缺(五):移动构造函数

C++温故补缺(五):移动构造函数

时间:2023-03-20 23:26:32浏览次数:58  
标签:std string int move C++ 移动 温故 构造函数

移动构造函数[C11新增]

参考:知乎:C++11右值引用和移动构造函数详解.知乎:什么是POD数据类型.

C++ 11之前,对象的拷贝由三个函数决定:拷贝构造函数,拷贝赋值运算符和析构函数。

C++ 11新增两个函数:移动构造函数和移动赋值运算符。

首先介绍移动语义(move),指以移动的方式而非深拷贝的方式初始化含有指针成员的类对象。也就是剥夺了用于初始化的对象的资源。

如:使用std::move()函数来初始化对象

#include<iostream>
using namespace std;

int main(){
   string str="hello";
   string ss=move(str);
   cout<<"str:"<<str<<endl<<"ss:"<<ss<<endl;

}

可以看到str字符串变为空了,也就是移动而非拷贝的方式初始化ss。

move

move在Cplusplus中的解释是:

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object.

In particular, std::move produces an xvalue expression that identifies its argument t. It is exactly equivalent to a static_cast to an rvalue reference type.

move函数是用于对象之间高效地转移资源的。也就是前面说的move语义,剥夺而非拷贝的方式获取资源。特别,move函数可以生成一个和它的参数t有关联的xvalue(指资源可以再利用的对象)表达式。也就是move会返回和参数类型相同的类型的表达式。完全等同于static_cast强制转换右值引用类型。

对于no-pod类型,move是以移动的方式获取资源,而pod类型,则是直接复制。并不会有参数的资源销毁。

pod类型是plain old data的缩写,指没有构造/析枸函数、复制/移动构造函数、复制/移动运算符的的数据类型。如int,char,float等。

而no-pod就是有这些东西的,如string,以及自定义的类

如:直接move()一个int

#include<iostream>
using namespace std;

int main(){
    int a=10;
    int b=move(a);
    cout<<"a:"<<a<<"  b:"<<b;
}

,move就并不会销毁a中的资源

再比如:没有定义移动构造函数的类的对象用move初始化

#include<iostream>
using namespace std;

class A{
   public:
   char *c;
   A(string s){
      this->c=&s[0];
   }

};
int main(){
   A a1("hello");
   A a2=move(a1);
   cout<<a2.c<<endl;
   cout<<a1.c;

}

,move也没有销毁参数的资源

所以是需要我们自己定义销毁行为的

#include<iostream>
using namespace std;

class A{
   public:
   char *c;
   A(string s){
      this->c=&s[0];
   }
   A(A &&temp){
      this->c=temp.c;
      temp.c=nullptr;
   }

};
int main(){
   A a1("hello");
   A a2=move(a1);
   cout<<a2.c<<endl;
   cout<<a1.c;

}

,这样就实现了移动。

为什么要销毁?

一般认为,移动资源后,原来的参数就不会再被访问到,为了保证这一点,需要手动置零/置空/释放内存,这也是对前面"高效"的解释。

标签:std,string,int,move,C++,移动,温故,构造函数
From: https://www.cnblogs.com/Tenerome/p/cppreview5.html

相关文章

  • C++温故补缺(四):构造函数和复制构造函数
    构造函数和复制构造函数构造函数对于需要传值的构造函数,如classbox{protected:intX;intY;intZ;public:box(int,in......
  • C++温故补缺(三):基本输入输出
    基本输入输出输出:cout<<输入:cin>>错误:cerr<<日志:clog<<在功能和调用上,cout,cerr和clog看上去无差别,cerr对象是非缓冲的,每个流插入到cerr后会立即输出,而clog......
  • C++温故补缺(二):lambda函数
    Lambda函数参考:CSDNC++11开始,提供了对匿名函数的支持,成为Lambda函数(表达式)通常,lambda函数用于封装传递给算法或异步方法的几行代码,对应不需要复用,且短小的函数,......
  • C++温故补缺(九):C++多态
    C++多态继承和派生当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态如:shape类被派生为两个类:Rectangle和Triangle#include<iostream>usingnamespacestd......
  • C++温故补缺(八):运算符重载和函数重载
    运算符重载和函数重载重载是c++多态性的一大体现,重载运算符是给运算符添加新的定义,使之前不能运算的对象变得可运算,且一般和运算符的意义相似.函数重载主要是同名函数......
  • C++温故补缺(七):;类的访问控制和继承
    类的访问控制和继承类的静态成员类的静态成员用关键字static修饰,类似静态变量或静态函数,也是有共享的概念类的静态变量:静态变量在类的所有对象中共享,不能再类的定......
  • C++温故补缺(六):友元函数、内联函数和this指针
    友元函数、内联函数和this指针友元函数友元函数是定义在类的外部,但有权访问类的所有私有(private)和保护(protectd)成员.友元函数的原型在类的定义中出现,但它并不是类......
  • C++温故补缺(十五):多线程
    多线程参考:CSDN,知乎传统C++(C++11之前)中并没有引入线程的概念,如果想要在C++中实现多线程,需要借助操作系统平台提供的API,如Linux的<pthread.h>,或windows下的<windows.......
  • C++温故补缺(十四):信号处理
    信号处理信号是由操作系统传给进程的中断,能够提前终止一个程序。在Unix,Linux,MacOS或Windows系统上,都可以通过Ctrl+C产生中断。下面是可以在程序中被捕获的信号,并且可......
  • C++温故补缺(十三):模板
    C++模板模板是泛型的基础,泛型编程就是一种独立于任何特殊类型的方式编写代码。模板就是创建泛型类或泛型函数的蓝图。STL库中的几个数据结构(vector,list,map等)以及算法......