返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++赋值函数+移动赋值函数+移动构造函数详解
  • 871
分享到

C++赋值函数+移动赋值函数+移动构造函数详解

2024-04-02 19:04:59 871人浏览 薄情痞子
摘要

目录左值引用和右值引用左值与右值左右值的切换左值引用:将左值绑定在引用上常量左值引用和非常量左值引用右值引用:将右值绑定在引用上常量右值引用和非常量右值引用移动构造函数赋值和移动赋值

左值引用和右值引用

左值与右值

左值:在内存中占有确定位置的对象,即左值占有内存。换句话来说,就是有地址,有值。

右值:不占内存(科学地讲是临时寄存器),仅有值,为临时变量。

左右值的切换

右值->左值:用*符号。

int a=10;
int* b=&a;// b为右值。
*b=20;// b为右值,*b为左值。

左值->右值:用&符号。

int a = 10;
&a = 40; //错误:赋值操作要求一个左值
int* b = &(a + 1); //错误:‘&'运算符要求一个左值,a为左值,但a+1为右值。
int* c = &a; //正确:var是左值

左值引用:将左值绑定在引用上

第一种情况,函数返回右值。

int global = 10;
int test()
{
return global;// 返回右值
}
int main()
{
test() = 20;// error,右值不可赋值!
cout << "test为:"<<test();
return 0;
}

第二种情况,函数返回左值。

int global = 10;
int& test()
{
return global;// 返回左值
}
int main()
{
test() = 20;// 左值可赋值
cout << "test为:"<<test();
return 0;
}

测试:

说明了左值引用让函数调用可以赋值成为可能。

常量左值引用和非常量左值引用

int a1=20; //非常量左值
const int a2=20; //常量左值
const int a3=20; //常量左值

//非常量左值引用
int &b1=a1; //正确,a1是一个非常量左值,可以被非常量左值引用绑定
int &b2=a2; //错误,a2是一个常量左值,不可以被非常量左值引用绑定
int &b3=20; //错误,10是一个非常量右值,不可以被非常量左值引用绑定
int &b4=a2+a3; //错误,(a2+a3)是一个常量右值,不可以被非常量左值引用绑定

//常量左值引用
const int &c1=a1; //正确,a1是一个非常量左值,可以被非常量右值引用绑定
const int &c2=a2; //正确,a2是一个常量左值,可以被非常量右值引用绑定
const int &c3=a1+a2; //正确,(a1+a2)是一个非常量右值,可以被常量右值引用绑定
const int &c4=a2+a3; //正确,(a2+a3)是一个常量右值,可以被非常量右值引用绑定

总结:

  • 1.非常量左值引用只能绑定到非常量左值上;
  • 2.常量左值引用可以绑定到非常量左值、常量左值、非常量右值、常量右值等所有类型。

(大->小,小引用绑大左值,常量左值范围更小嘛)

右值引用:将右值绑定在引用上

常量右值引用和非常量右值引用

总结:

  • 1.非常量右值引用只能绑定到非常量右值上;
  • 2.常量右值引用可以绑定到非常量右值、常量右值上。

移动构造函数

小狗狗类:

Dog(int age,string name) :m_age(new int(age)), m_name(name){}
Dog(Dog& d):m_age(d.m_age),m_name(d.m_name)
{
cout << "我是拷贝构造函数······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移动构造函数······" << endl;
}
int* m_age;
string m_name;#include<string>
#include<iOStream>
using namespace std;
class Dog
{
public:
Dog(){};
Dog(int age,string name) :m_age(new int(age)), m_name(name){}
Dog(Dog& d):m_age(d.m_age),m_name(d.m_name)
{
cout << "我是拷贝构造函数······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移动构造函数······" << endl;
}
int* m_age;
string m_name;
};

客户端类:

#include"construct.h"
int main()
{
int age = 19;
string name = "小狗狗";
Dog d1(age, name);
cout << "d1:" <<* d1.m_age << d1.m_name << endl;
Dog d2(move(d1));
bool is = d1.m_age == nullptr;
cout << is << endl;
cout << "d2.age:" << *d2.m_age <<endl<< "d2.name:" <<d2.m_name << endl;
return 0;
}

测试:

说明了移动构造运行成功,d1销毁了,d2获取到了d1的内存。

赋值和移动赋值函数

赋值函数类:

#include<String>
using namespace std;
class Cat
{
public:
Cat(){}
Cat(int age ,string name):age(age),name(name) {}
Cat& operator=(Cat& c)
{
if (this!= &c)
{
age = c.age;
name = c.name;
}
return *this;
}
int age;
string name;
};

移动赋值函数类:

#include"assign.h"
class Dog
{
public:
Dog() {}
Dog(int age, string name) :age(new int(age)), name(name) {}

Dog& operator=(Dog&& c)
{
age = c.age;
name = c.name;
c.age = nullptr;
return *this;
}
int* age;
string name;
};

客户端类:

#include<iostream>
#include"moveAssign.h"
int main()
{
cout << "赋值函数" << endl;
Cat c1(18, "小猫咪");
Cat c2 ;
c2 = c1;
cout << "c1.age:" << c1.age << endl << "c1.name" << c1.name << endl;
cout << "c2.age:" << c2.age << endl << "c2.name" << c2.name << endl<<endl;;
cout << "移动赋值函数" << endl;
Dog d1(19,"小狗狗");
cout << "d1.age:" << *d1.age << endl << "d1.name" << d1.name << endl << endl;
Dog d2;
d2 = move(d1);
bool is = (d1.age == nullptr);
cout << "d1是否为空:" << is << endl;
cout << "d2.age:" << *d2.age << endl << "d2.name" << d2.name << endl;
return 0;
}

测试:

到此这篇关于c++赋值函数+移动赋值函数+移动构造函数详解的文章就介绍到这了,更多相关C++赋值函数 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++赋值函数+移动赋值函数+移动构造函数详解

本文链接: https://lsjlt.com/news/166375.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++赋值函数+移动赋值函数+移动构造函数详解
    目录左值引用和右值引用左值与右值左右值的切换左值引用:将左值绑定在引用上常量左值引用和非常量左值引用右值引用:将右值绑定在引用上常量右值引用和非常量右值引用移动构造函数赋值和移动赋值...
    99+
    2024-04-02
  • C++移动构造函数和移动赋值的用法
    本篇内容介绍了“C++移动构造函数和移动赋值的用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!移动构造函数首先看通常的拷贝构造函数:拷贝构...
    99+
    2023-06-19
  • C++构造析构赋值运算函数应用详解
    目录了解C++默默编写哪些函数不想使用编译器函数为多态基类声明virtual析构函数别让异常逃离析构函数绝不在构造和析构过程中调用virtual函数令operator=返回一个ref...
    99+
    2024-04-02
  • C++右值引用与移动构造函数基础与应用详解
    目录1.右值引用1.1左值右值的纯右值将亡值右值1.2右值引用和左值引用2.移动构造函数2.1完美的移动转发1.右值引用 右值引用是 C++11 引入的与 Lambda 表达式齐名的...
    99+
    2023-02-13
    C++右值引用 C++移动构造函数
  • C++11移动构造函数的使用
    目录一、引言二、左值和右值三、深拷贝构造函数四、右值引用五、移动构造函数六、std::move()七、参考资料一、引言 移动构造函数是什么?先举个例子,你有一本书,你不想看,但我很想...
    99+
    2024-04-02
  • C++11怎么移动构造函数通常
    这篇文章主要讲解了“C++11怎么移动构造函数通常”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++11怎么移动构造函数通常”吧!不会抛出异常的移动构造函数拷贝构造函数通常伴随着内存分配操...
    99+
    2023-06-19
  • 聊聊C++中右值引用和移动构造函数的使用
    目录一: 背景二: 右值引用1. 它到底解决了什么问题2. 右值引用是个什么样子三: 右值引用如何减少对象的创建1. 简要思路2. 一个简单的例子3. 性能优化方案四: 总结一: 背...
    99+
    2024-04-02
  • ES6解构赋值(数组,对象,函数)使用详解
    目录解构赋值数组解构默认值对象解构剩余模式(pattern)"…"嵌套解构智能函数参数总结解构赋值 JavaScript 中最常用的两种数据结构是 ...
    99+
    2022-11-16
    ES6解构赋值使用 ES6解构赋值 ES6数组解构赋值 ES6解构赋值对象
  • C++中有哪些赋值函数
    今天就跟大家聊聊有关C++中有哪些赋值函数,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。C++赋值函数相关代码示例:// test.cpp  #include&n...
    99+
    2023-06-17
  • C++11中移动构造函数案例代码
    目录1. 拷贝构造函数中的深拷贝问题2. C++移动构造函数(移动语义的具体实现)1. 拷贝构造函数中的深拷贝问题 在 C++ 98/03 标准中,如果想用其它对象初始化一个同类的新...
    99+
    2023-01-04
    C++11移动构造函数 C++11构造函数 C++构造函数
  • C++右值引用与移动构造函数应用的方法是什么
    这篇文章主要讲解了“C++右值引用与移动构造函数应用的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++右值引用与移动构造函数应用的方法是什么”吧!1.右值引用右值引用是 C++...
    99+
    2023-07-05
  • C++:构造函数,析构函数详解
    目录前言一、面向对象二、构造函数1.基本概念2.构造函数重载1.构造函数分类2.有参构造函数:3.有参构造函数3个调用规则:4.拷贝构造函数5.析构函数总结前言 上期了解C++类中有...
    99+
    2024-04-02
  • vb中array函数如何赋值
    在VB中,可以使用Array函数将一个或多个值赋给数组。如果要将单个值赋给数组,可以使用以下语法:```Dim myArray As...
    99+
    2023-10-11
    vb
  • C#构造函数详解
    一、简介 构造函数,基本用法是在类对象声明的时候完成初始化工作。 二、实例构造函数 1、构造函数的名字与类名相同。 2、使用 new 表达式创建类的对象或者结构(例如int)时,会调...
    99+
    2024-04-02
  • 详解C++构造函数
    目录1.作用2.代码举例2.1 示例1:2.2 示例2:3. 使用3.1 使用构造函数初始化3.2 有参数的构造函数3.3 默认的构造函数4. 成员初始化列表例1:正常初始化例2:成...
    99+
    2024-04-02
  • C++构造函数详解
    文章转自公众号:Coder梁(ID:Coder_LT) 上一篇文章我们介绍了定义了类,在使用之前,往往还需要对类进行初始化。这篇介绍的就是对类进行初始化的方法。 像是结构体,我们可以...
    99+
    2024-04-02
  • php函数的参数赋值有哪些
    这篇文章主要介绍“php函数的参数赋值有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php函数的参数赋值有哪些”文章能帮助大家解决问题。php函数的参数赋值有3种:1、值传递赋值,将实参的值复...
    99+
    2023-06-30
  • c++中void函数不能赋值为什么
    c++kquote>在c++中,void函数不能赋值,原因如下:类型不匹配:void函数没有返回值,类型为void,与赋值运算符操作数类型不兼容。函数指针的本质:void函数没有返...
    99+
    2024-05-09
    c++
  • vue实现动态给data函数中的属性赋值
    目录vue动态给data函数中的属性赋值vue给data中的数据赋值报错问题背景分析解决方案vue动态给data函数中的属性赋值 1.首先创建一个监视器,用来监视相关的属性 2.当这...
    99+
    2024-04-02
  • C++中构造函数详解
    构造函数按参数为为:有参构造函数和无参构造函数 按类型分为:普通构造函数和拷贝构造函数 构造函数的三种调用方法:括号法,显示法,隐式转换法; //括号法 Person p1; ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作