Environment: Windows10 64bit Visual Studio 2017 C++11
引言:右值引用的作用即实现"转移语义"和"完美转发"
右值和右值引用
dword - 4byte sizeof( int ) - 4byte
qword - 8byte sizeof( void* ) - 8byte
Disassembly:(普通变量,引用,右值引用,指针变量)的区别
其中C++代码的第一行与第三行的10均为右值,其余均是左值(左值不一定只在左边,右值一定在右边)。
实质是右值是临时量,而左值是已经在内存中有一席之地。注意:右值 != 右值引用。
int var1 = 10;
00007FF620343B8B mov dword ptr [var1],0Ah
int &var2 = var1;
00007FF620343B92 lea rax,[var1]
00007FF620343B96 mov qword ptr [var2],rax
int &&var3 = 10;
00007FF620343B9A mov dword ptr [rbp+64h],0Ah
00007FF620343BA1 lea rax,[rbp+64h]
00007FF620343BA5 mov qword ptr [var3],rax
var3 = var2;
00007FF620343BA9 mov rax,qword ptr [var3]
00007FF620343BAD mov rcx,qword ptr [var2]
00007FF620343BB1 mov ecx,dword ptr [rcx]
00007FF620343BB3 mov dword ptr [rax],ecx
const int &var4 = 100;
00007FF620343BB5 mov dword ptr [rbp+0A4h],64h
00007FF620343BBF lea rax,[rbp+0A4h]
00007FF620343BC6 mov qword ptr [var4],rax
int* p1 = nullptr;
00007FF620343BCD mov qword ptr [p1],0
p1 = new int(0);
00007FF620343BD8 mov ecx,4
00007FF620343BDD call operator new (07FF620311A22h)
00007FF620343BE2 mov qword ptr [rbp+1A8h],rax
00007FF620343BE9 cmp qword ptr [rbp+1A8h],0
00007FF620343BF1 je main+0C0h (07FF620343C10h)
00007FF620343BF3 mov rax,qword ptr [rbp+1A8h]
00007FF620343BFA mov dword ptr [rax],0
00007FF620343C00 mov rax,qword ptr [rbp+1A8h]
00007FF620343C07 mov qword ptr [rbp+1D8h],rax
00007FF620343C0E jmp main+0CBh (07FF620343C1Bh)
00007FF620343C10 mov qword ptr [rbp+1D8h],0
00007FF620343C1B mov rax,qword ptr [rbp+1D8h]
00007FF620343C22 mov qword ptr [p1],rax
*p1 = var1;
00007FF620343C29 mov rax,qword ptr [p1]
00007FF620343C30 mov ecx,dword ptr [var1]
00007FF620343C33 mov dword ptr [rax],ecx
*p1 = var2;
00007FF620343C35 mov rax,qword ptr [p1]
00007FF620343C3C mov rcx,qword ptr [var2]
00007FF620343C40 mov ecx,dword ptr [rcx]
00007FF620343C42 mov dword ptr [rax],ecx
*p1 = var3;
00007FF620343C44 mov rax,qword ptr [p1]
00007FF620343C4B mov rcx,qword ptr [var3]
00007FF620343C4F mov ecx,dword ptr [rcx]
00007FF620343C51 mov dword ptr [rax],ecx
delete p1;
00007FF620343C53 mov rax,qword ptr [p1]
00007FF620343C5A mov qword ptr [rbp+1C8h],rax
00007FF620343C61 mov edx,4
00007FF620343C66 mov rcx,qword ptr [rbp+1C8h]
00007FF620343C6D call operator delete (07FF620310BAEh)
00007FF620343C72 cmp qword ptr [rbp+1C8h],0
00007FF620343C7A jne main+139h (07FF620343C89h)
00007FF620343C7C mov qword ptr [rbp+1D8h],0
00007FF620343C87 jmp main+152h (07FF620343CA2h)
00007FF620343C89 mov qword ptr [p1],8123h
delete p1;
00007FF620343C94 mov rax,qword ptr [p1]
00007FF620343C9B mov qword ptr [rbp+1D8h],rax
int get1()
{
00007FF7346D5FE0 push rbp
00007FF7346D5FE2 push rdi
00007FF7346D5FE3 sub rsp,108h
00007FF7346D5FEA lea rbp,[rsp+20h]
00007FF7346D5FEF mov rdi,rsp
00007FF7346D5FF2 mov ecx,42h
00007FF7346D5FF7 mov eax,0CCCCCCCCh
00007FF7346D5FFC rep stos dword ptr [rdi]
00007FF7346D5FFE lea rcx,[__2D0EBEBB_windows_stl@cpp (07FF73475F318h)]
00007FF7346D6005 call __CheckForDebuggerJustMyCode (07FF734600CD0h)
int a = 0;
00007FF7346D600A mov dword ptr [a],0
return 100;
00007FF7346D6011 mov eax,64h
}
00007FF7346D6016 lea rsp,[rbp+0E8h]
00007FF7346D601D pop rdi
00007FF7346D601E pop rbp
00007FF7346D601F ret
mov eax,64h 生成100(4Byte)放入eax寄存器
mov dword ptr [var5],eax 将寄存器中的100(4Byte)放到起始地址为var5的内存空间(4Byte)
int var5 = get1();
00007FF734633CA2 call get1 (07FF734604B8Ch)
00007FF734633CA7 mov dword ptr [var5],eax
int var6 = get2();
00007FF734633CAD call get2 (07FF734604B91h)
00007FF734633CB2 mov eax,dword ptr [rax]
00007FF734633CB4 mov dword ptr [var6],eax
mov dword ptr [rbp+0E4h],64h 生成100(4Byte)放入内存为rbp+0E4h的内存空间
lea rax,[rbp+0E4h] 将地址空间为rbp+0E4h的内存的地址值(8Byte)放入寄存器rax
mov eax,dword ptr [rax] 将内存地址为寄存器rax中的值的内存空间的100
mov dword ptr [var6],eax
int&& get2()
{
00007FF7346DBB00 push rbp
00007FF7346DBB02 push rdi
00007FF7346DBB03 sub rsp,128h
00007FF7346DBB0A lea rbp,[rsp+20h]
00007FF7346DBB0F mov rdi,rsp
00007FF7346DBB12 mov ecx,4Ah
00007FF7346DBB17 mov eax,0CCCCCCCCh
00007FF7346DBB1C rep stos dword ptr [rdi]
00007FF7346DBB1E lea rcx,[__2D0EBEBB_windows_stl@cpp (07FF73475F318h)]
00007FF7346DBB25 call __CheckForDebuggerJustMyCode (07FF734600CD0h)
int a = 0;
00007FF7346DBB2A mov dword ptr [a],0
return 100;
00007FF7346DBB31 mov dword ptr [rbp+0E4h],64h
00007FF7346DBB3B lea rax,[rbp+0E4h]
}
00007FF7346DBB42 lea rsp,[rbp+108h]
00007FF7346DBB49 pop rdi
00007FF7346DBB4A pop rbp
00007FF7346DBB4B ret
C++ STL - std::move()