首页 > 其他分享 >移动语义和引用折叠、完美转发

移动语义和引用折叠、完美转发

时间:2024-04-23 22:47:56浏览次数:27  
标签:对象 折叠 语义 内存 转发 拷贝 移动 赋值

移动构造、移动赋值

C++11新增了移动语义新特性,移动语义允许在不复制数据的情况下转移资源的所有权。在这之前,对象通过拷贝构造函数拷贝赋值运算符进行传递,发生大量的数据复制,导致性能下降。

以常用的string对象为例,

#include <cstring>
#include <iostream>
class string {
public:
  string(const char *p = nullptr) {
    std::cout << "default ctor" << std::endl;
    if (p != nullptr) {
      _data = new char[strlen(p) + 1];
      strcpy(_data, p);
    } else {
      _data = new char[1];
      *_data = '\0';
    }
  }
  ~string() {
    std::cout << "destructor" << std::endl;
    delete[] _data;
    _data = nullptr;
  }
  string(const string &str) {
    std::cout << "copy ctor" << std::endl;
    _data = new char[strlen(str._data) + 1];
    strcpy(_data, str._data);
  }
  string &operator=(const string &str) {
    std::cout << "copy assignment" << std::endl;
    if (this == &str) {
      return *this;
    }
    delete[] _data;
    _data = new char[strlen(str._data) + 1];
    strcpy(_data, str._data);
    return *this;
  }
  string(string &&str) {
    std::cout << "move ctor" << std::endl;
    _data = str._data;
    str._data = nullptr;
  }
  string &operator=(string &&str) {
    std::cout << "move assignment" << std::endl;
    if (this == &str)
      return *this;
    delete[] _data;
    _data = str._data;
    str._data = new char[1];
    str._data[0] = '\0';
    return *this;
  }
  const char *c_str() const { return _data; }

private:
  char *_data;
};
string foo(const string &val) {
  const char *str = val.c_str();
  string tmp(str);
  return tmp;
}
int main() {
  string str1("hello");
  string str2("world");
  str2 = foo(str1);
  std::cout << str2.c_str() << std::endl;
  return 0;
}

如果没有移动语义,上面这段代码中会发生两次拷贝,
第一次是foo函数的返回,会发生一次拷贝构造main函数栈帧上的临时对象(开辟内存,拷贝数据),然后析构tmp(释放内存)。
第二次是str2的拷贝赋值,将main函数栈帧上的临时对象拷贝赋值给str2,又是开辟内存,拷贝数据,然后析构临时对象。

因此没有移动语义,对象的传递将会发生大量的拷贝,尤其是各种临时对象的返回以及临时对象的赋值运算重载。

在增加移动语义后,由tmp构造main函数栈帧临时对象时,不用开辟新的内存,而是直接把tmp中的char*移动到临时对象中,这种资源的所有权转移,避免了内存的开辟释放,以及数据拷贝。同理,main函数栈帧临时对象赋值给str2时,也是直接转移char*即可。

这便是移动语义的好处:减少不必要的内存开辟和释放以及数据拷贝。

std::move()的使用

标签:对象,折叠,语义,内存,转发,拷贝,移动,赋值
From: https://www.cnblogs.com/ericling0529/p/18150315

相关文章

  • 语义搜索相关配置
    1.打开services项目,在pom文件中引入依赖如下<dependency><groupId>com.hankcs</groupId><artifactId>hanlp</artifactId><version>portable-1.8.3</version></dependency>2.在hanlpgithub下载语言模型,放入项目根目录下3.在service......
  • 06、M-LAG正常工作场景流量转发
    M-LAG正常工作场景流量转发M-LAG双活系统建立成功后即进入正常的工作,M-LAG主备设备负载分担共同进行流量的转发,转发行为没有区别。下面介绍M-LAG在正常工作情况下是如何进行流量转发的。单播流量转发单播流量转发包括二层已知单播转发和三层单播转发。如图1所示,M-LAG双活系......
  • 07、M-LAG故障场景流量转发
    M-LAG故障场景流量转发M-LAG作为一种跨设备链路聚合的技术,把链路可靠性从单板级提高到了设备级。如果出现故障(不管是链路故障、设备故障还是peer-link故障),M-LAG都能够保证正常的业务不受影响,下面介绍M-LAG在故障情况下是如何保障业务的正常运行的。上行链路故障图1 上行链......
  • windows端口转发
    windows端口转发windows提供端口转发功能,命令netshinterfaceportproxyhelp命令打印帮助信息netshinterfaceportproxyshowallshow命令showall-显示所有端口代理参数。showv4tov4-显示IPv4代理连接到另一个IPv4端口的参数。showv4tov6-......
  • stm32采集烟雾和温湿度+ESP8266转发解析+python构造http
      https://www.cnblogs.com/gooutlook/p/16061136.html  http://192.168.1.103/Control_SensorPin?sensor=sensor_all&action=GetDatapython#-*-coding:utf-8-*-importrequestsimporturllib.parse#pipinstallrequestsdefSendHttp():#ht......
  • uRPF(Unicast Reverse Path Forwarding,单播反向路径转发)
    uRPF(UnicastReversePathForwarding)概念和原理这是网络设备的一个安全特性,主要功能是用于防止基于源地址欺骗的网络攻击行为,说简单一点就是在IP数据包转发的时候不单基于目的地址查看路由表,对源地址同样进行查表,如未能查到路由(一般不是默认路由,但根据策略不同行为稍有区别),则......
  • 请求转发和请求重定向的区别
    请求转发(Forward)和请求重定向(Redirect)虽然都是HTTP服务器,处理客户端请求时进行(页面)跳转的实现方式,但是二者有以下5点不同:1.定义不同。2.跳转方不同。3.数据共享不同。4.最终URL地址不同。5.代码实现不同。具体内容如下:①定义不同请求转发(Forward):发......
  • GO语言实现TCP端口转发
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061package main import (    "fmt"    "log"    "net&......
  • 基于融合语义信息改进的内容推荐算法。Improved content recommendation algorithm in
    引言路漫漫其修远兮,吾将上下而求索。每天一篇论文,做更好的自己。本文读的这篇论文为发表于2023年5月28日的一篇名为《基于融合语义信息改进的内容推荐算法》(基于融合语义信息改进的内容推荐算法)的文章,文章主要介绍了基于内容的推荐技术在电子商务和教育领域的广泛应用,以及传统基......
  • 第6天:基础入门-抓包技术&HTTPS协议&APP&小程序&PC应用&WEB&转发联动
    第六天一、抓包技术-HTTP/S-Web&APP&小程序&PC应用想要抓包都必须要配置代理和端口,这些工具只能抓取HTTP/S协议的数据,走其他协议的数据抓不了有些APP具有代理检测功能,若发现你开启了代理,直接无法访问APP1.Web网页:安装完抓包软件之后,需要在软件上导出CA证书,在浏览器上......