对象与基本类型按引用传递的差异及指针转换疑问
搞懂C++引用传递的本质:为什么你不能直接把引用赋值给指针?
咱们先把这个问题拆透——你混淆了C里引用和指针的核心概念,这也是很多刚接触C的开发者容易踩的坑。先从你写的代码错误说起,再一步步解释清楚。
首先,纠正你代码里的两个小问题
你写的meowName方法里有两处错误:
- 试图把引用
cat直接赋值给指针pCat,这是类型不匹配的; - 类里的成员是
_name,你代码里写的是pCat->name,会编译报错。
正确的写法应该是:
void Cat::meowName(Cat &cat){ Cat *pCat = &cat; // 用&取引用对应的对象地址 printf("My name is: %s\n", pCat->_name); }
核心问题:引用到底是什么?
很多人会误以为引用是“伪装的指针”或者“地址”,但实际上引用是变量/对象的别名——它和原变量指向同一块内存空间,但它本身不是指针(不是存储地址的变量)。
举个最简单的例子:
int num = 100; int &num_ref = num; // num_ref是num的别名 num_ref = 200; // 此时num的值也变成200,因为它们是同一个东西
你可以把引用理解成原变量的“外号”,喊外号和喊本名,都是指同一个人。所以在你的swap函数里,int &a就是main里a的别名,操作a就等同于直接修改原变量,这也是为什么交换后main里的a和b值会变。
为什么你不能直接把引用赋值给指针?
指针的作用是存储内存地址,而引用是对象的别名,本身就是对象的“化身”,不是地址。如果要获取这个对象的地址,必须用取地址符&——&cat就是获取cat这个别名对应的对象的内存地址,这个地址值才能赋值给指针pCat。
换句话说,你不能把“人”直接当成“门牌号”,但你可以通过“人”拿到他的门牌号(&操作),再把门牌号给指针。
额外补充:其实你根本不需要转成指针
既然cat是原对象的别名,你完全可以直接用cat._name访问成员,没必要多此一举转成指针:
void Cat::meowName(Cat &cat){ printf("My name is: %s\n", cat._name); }
再区分下三种传递方式的本质
为了彻底搞清楚,咱们对比下三种参数传递:
- 值传递:函数会创建传入变量的副本,函数里操作的是副本,修改不会影响原变量。比如
void swap(int a, int b),交换的是副本,原a和b纹丝不动。 - 引用传递:传递的是原对象的别名,没有副本,函数里操作的就是原对象本身,修改直接同步到原变量。
- 指针传递:传递的是原对象的地址(一个存储地址的指针变量),函数里通过指针间接操作原对象,也能修改原变量,但指针本身是独立的变量(比如你可以修改指针指向别的对象),这和引用的“绑定后不能改指向”的特性完全不同。
总结一下
引用不是地址,它是原对象的“另一个名字”,和原对象共享同一块内存。当你需要把它转换成指针时,必须用&取地址符获取对象的内存地址。指针是存储地址的变量,和引用是完全不同的概念,别搞混啦!
内容的提问来源于stack exchange,提问作者Zesa Rex
相关产品推荐
相关产品推荐

