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

目录

左值引用和右值引用

左值与右值

左右值的切换

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

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

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

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

移动构造函数

赋值和移动赋值函数

左值引用和右值引用 左值与右值

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

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

左右值的切换

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

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++赋值函数 内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    excel怎么用乘法函数

    excel怎么用乘法函数,乘法,函数,哪个,excel乘法函数怎么用?1、首先用鼠标选中要计算的单元格。2、然后选中单元格后点击左上方工具栏的fx公

    excel中乘法函数是什么?

    excel中乘法函数是什么?,乘法,函数,什么,打开表格,在C1单元格中输入“=A1*B1”乘法公式。以此类推到多个单元。1、A1*B1=C1的Excel乘法公式

    标准差excel用什么函数?

    标准差excel用什么函数?,函数,标准,什么,在数据单元格的下方输入l标准差公式函数公式“=STDEVPA(C2:C6)”。按下回车,求出标准公差值。详细

    excel常用函数都有哪些?

    excel常用函数都有哪些?,函数,哪些,常用,1、SUM函数:SUM函数的作用是求和。函数公式为=sum()例如:统计一个单元格区域:=sum(A1:A10)  统计多个

    EXCEL最常用的函数有哪些?

    EXCEL最常用的函数有哪些?,函数,哪些,常用,一、IF函数作用:条件判断,根据判断结果返回值。用法:IF(条件,条件符合时返回的值,条件不符合时返回