C++賦值函數(shù)+移動(dòng)賦值函數(shù)+移動(dòng)構(gòu)造函數(shù)詳解
左值引用和右值引用
左值與右值
左值:在內(nèi)存中占有確定位置的對(duì)象,即左值占有內(nèi)存。換句話來(lái)說(shuō),就是有地址,有值。
右值:不占內(nèi)存(科學(xué)地講是臨時(shí)寄存器),僅有值,為臨時(shí)變量。
左右值的切換
右值->左值:用*符號(hào)。
int a=10; int* b=&a;// b為右值。 *b=20;// b為右值,*b為左值。
左值->右值:用&符號(hào)。
int a = 10; &a = 40; //錯(cuò)誤:賦值操作要求一個(gè)左值 int* b = &(a + 1); //錯(cuò)誤:‘&'運(yùn)算符要求一個(gè)左值,a為左值,但a+1為右值。 int* c = &a; //正確:var是左值
左值引用:將左值綁定在引用上
第一種情況,函數(shù)返回右值。
int global = 10;
int test()
{
return global;// 返回右值
}
int main()
{
test() = 20;// error,右值不可賦值!
cout << "test為:"<<test();
return 0;
}第二種情況,函數(shù)返回左值。
int global = 10;
int& test()
{
return global;// 返回左值
}
int main()
{
test() = 20;// 左值可賦值
cout << "test為:"<<test();
return 0;
}測(cè)試:

說(shuō)明了左值引用讓函數(shù)調(diào)用可以賦值成為可能。
常量左值引用和非常量左值引用
int a1=20; //非常量左值 const int a2=20; //常量左值 const int a3=20; //常量左值 //非常量左值引用 int &b1=a1; //正確,a1是一個(gè)非常量左值,可以被非常量左值引用綁定 int &b2=a2; //錯(cuò)誤,a2是一個(gè)常量左值,不可以被非常量左值引用綁定 int &b3=20; //錯(cuò)誤,10是一個(gè)非常量右值,不可以被非常量左值引用綁定 int &b4=a2+a3; //錯(cuò)誤,(a2+a3)是一個(gè)常量右值,不可以被非常量左值引用綁定 //常量左值引用 const int &c1=a1; //正確,a1是一個(gè)非常量左值,可以被非常量右值引用綁定 const int &c2=a2; //正確,a2是一個(gè)常量左值,可以被非常量右值引用綁定 const int &c3=a1+a2; //正確,(a1+a2)是一個(gè)非常量右值,可以被常量右值引用綁定 const int &c4=a2+a3; //正確,(a2+a3)是一個(gè)常量右值,可以被非常量右值引用綁定
總結(jié):
- 1.非常量左值引用只能綁定到非常量左值上;
- 2.常量左值引用可以綁定到非常量左值、常量左值、非常量右值、常量右值等所有類型。
(大->小,小引用綁大左值,常量左值范圍更小嘛)
右值引用:將右值綁定在引用上
常量右值引用和非常量右值引用

總結(jié):
- 1.非常量右值引用只能綁定到非常量右值上;
- 2.常量右值引用可以綁定到非常量右值、常量右值上。
移動(dòng)構(gòu)造函數(shù)
小狗狗類:
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 << "我是拷貝構(gòu)造函數(shù)······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移動(dòng)構(gòu)造函數(shù)······" << 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 << "我是拷貝構(gòu)造函數(shù)······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移動(dòng)構(gòu)造函數(shù)······" << 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;
}測(cè)試:

說(shuō)明了移動(dòng)構(gòu)造運(yùn)行成功,d1銷毀了,d2獲取到了d1的內(nèi)存。
賦值和移動(dòng)賦值函數(shù)
賦值函數(shù)類:
#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;
};移動(dòng)賦值函數(shù)類:
#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 << "賦值函數(shù)" << 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 << "移動(dòng)賦值函數(shù)" << 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è)試:

到此這篇關(guān)于C++賦值函數(shù)+移動(dòng)賦值函數(shù)+移動(dòng)構(gòu)造函數(shù)詳解的文章就介紹到這了,更多相關(guān)C++賦值函數(shù) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中jsoncpp庫(kù)和nlohmann-json庫(kù)實(shí)現(xiàn)JSON與字符串類型轉(zhuǎn)換
jsoncpp是ROS自帶的一個(gè)JSON庫(kù),它提供了一些函數(shù)來(lái)解析和生成JSON數(shù)據(jù),在ROS中,可以使用jsoncpp庫(kù)來(lái)實(shí)現(xiàn)JSON與字符串類型之間的轉(zhuǎn)換,這篇文章主要介紹了jsoncpp庫(kù)和nlohmann-json庫(kù)實(shí)現(xiàn)JSON與字符串類型轉(zhuǎn)換,需要的朋友可以參考下2023-08-08
C++11新特性之隨機(jī)數(shù)庫(kù)(Random?Number?Library)詳解
相對(duì)于C++11之前的隨機(jī)數(shù)生成器來(lái)說(shuō),C++11的隨機(jī)數(shù)生成器是復(fù)雜了很多,下面這篇文章主要給大家介紹了關(guān)于C++11新特性之隨機(jī)數(shù)庫(kù)(Random?Number?Library)的相關(guān)資料,需要的朋友可以參考下2022-06-06
利用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單三子棋游戲
這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
詳解C++設(shè)計(jì)模式編程中責(zé)任鏈模式的應(yīng)用
這篇文章主要介紹了C++設(shè)計(jì)模式編程中責(zé)任鏈模式的應(yīng)用,責(zé)任鏈模式使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,需要的朋友可以參考下2016-03-03
基于一個(gè)簡(jiǎn)單定長(zhǎng)內(nèi)存池的實(shí)現(xiàn)方法詳解
本篇文章對(duì)一個(gè)簡(jiǎn)單定長(zhǎng)內(nèi)存池的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05
C語(yǔ)言動(dòng)態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解
但是在實(shí)際的編程中,往往會(huì)發(fā)生這種情況,即所需的內(nèi)存空間取決于實(shí)際輸入的數(shù)據(jù),而無(wú)法預(yù)先確定 。為了解決上述問(wèn)題,C語(yǔ)言提供了一些內(nèi)存管理函數(shù),這些內(nèi)存管理函數(shù)可以按需要?jiǎng)討B(tài)的分配內(nèi)存空間,也可把不再使用的空間回收再次利用2022-12-12
C語(yǔ)言程序設(shè)計(jì)50例(經(jīng)典收藏)
本篇文章是對(duì)C語(yǔ)言程序設(shè)計(jì)的50個(gè)小案例進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06

