文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

左值引用和右值引用

左值与右值

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

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

左右值的切换

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

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)是一个常量右值,可以被非常量右值引用绑定

总结:

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

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

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

总结:

移动构造函数

小狗狗类:

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++赋值函数 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯