C++中的引用和传值

本文探讨了C++中按引用和按值传参数的问题,包括*this + n 的优先级解析,以及为何使用传引用。通过实例和汇编代码分析,解释了传引用与传值的区别,指出传引用不会影响原始变量,而传值会创建新的变量副本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++中的按引用和按值传参数问题

问题描述

今天朋友问我关于C++对象中的this的问题,大概的代码就是

	return *this = *this + n;

我没系统学过C++,也很是困惑,主要有以下几点:

  1. *this + n 是哪一个优先级高
  2. 为什么要用传引用

*this + n 哪个的优先级高

这个问题比较好解决,这里很明显是吧this加上了n个对象的长度,得到了的地址。相似的,在*p + n; *p++; 都是先加地址。

为什么要用传引用

我们都知道按引用传参数,是把传入的参数的内存空间完全复制给了参数,这样参数就有了和调用函数之前的变量一样的地址,一样的空间,只是名字不一样。那么传值之后,取这个值得地址是不是也行呢?于是我写了一下两个程序做了实验:

#include <iostream>
int reference(int &num);
int main(){
	int num[] = {1,2,3,4};
	reference(num[0]);
}
int reference(int &num){
	return *&num = *&num + 1;
}
#include <iostream>
int copy(int num);
int main(){
	int num[] = {1,2,3,4};
	reference(num[0]);
}
int copy(int num){
	return *&num = *&num + 1;
}

我的猜想就是:

  •   传值进去之后,%rdi 里的内容是(%rsp),也就是寄存器里放着这个变量的值;
    
  •   传引用,%rdi里的内容应该是%rsp,也即放着这个变量的地址
    

于是我在Debian 9.5 x86-64 objdump 看了两个程序的汇编代码,两段代码分别如下:

push 	%rbp
mov 	%rsp,%rbp
sub		$0x10,%rsp
movl	$0x1,-0x10(%rbp)
movl	$0x2,-0xc(%rbp)
movl	$0x3,-0x8(%rbp)
movl	$0x4,-0x4(%rbp)
lea		-0x10(%rbp),%rax
mov 	%rax, %rdi
callq	<reference>
push 	%rbp
mov 	%rsp,%rbp
sub		$0x10,%rsp
movl	$0x1,-0x10(%rbp)
movl	$0x2,-0xc(%rbp)
movl	$0x3,-0x8(%rbp)
movl	$0x4,-0x4(%rbp)
mov		-0x10(%rbp),%eax
mov 	%eax, %edi
callq	<copy>

main函数里只有一个区别,reference(int &num)是把num的地址传进去了,相当于reference(int* num),两者的区别只是C++对传地址进行了封装,在调用按引用传参的函数的时候,只需要穿进去值,即reference(num[0]);后者则需要把地址传进去,即reference(num);
copy(int num)则仅仅是传进去值,在copy函数里,如果需要使用到这个变量的地址,函数将会把%rdipush到栈上,取到的地址也是这个新变量的地址,这个变量和调用者的变量只有一个联系,值是一样的,如果对这个新变量进行修改,是不会影响旧变量的。

只是学习中遇到的一个问题,不喜勿喷,记录以免下次思维混乱。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值