引用类型
引用类型就是变量的别名,其在初始化时必须要赋值。
// 基本类型
int
x =
1
;
int
& ref = x;
ref =
2
;
printf(
"%d \n"
,ref);
// 类
Person p;
Person& ref = p;
ref.x =
10
;
printf(
"%d \n"
,p.x);
// 指针类型
int
****** x = (
int
******)
1
;
int
******& ref = x;
ref = (
int
******)
2
;
printf(
"%d \n"
,x);
// 数组类型
int
arr[] = {
1
,
2
,
3
};
int
(&p)[
3
] = arr;
p[
0
] =
4
;
printf(
"%d \n"
,arr[
0
]);
如上是引用类型作用在各个类型下的例子,那么引用类型是如何实现的呢?其本质是什么?我们可以看下反汇编代码:
会发现这段反汇编和指针的反汇编一模一样的:
这时候我们暂时的出结论:引用类型就是指针。
但如果引用类型就是指针,为什么C++需要新创建一个引用类型的概念呢?它们之间必然存在着一些区别,我们可以从初始化、运算、赋值来看反汇编代码的区别:
我们可以很清晰的看见区别从运算到赋值都不一样,指针运算到赋值改变的是指针本身,而不是指针指向的那个地址,而引用则不一样其从运算到赋值改变的是所引用的变量,我们得出这几个结论:
-
引用必须赋初始值,且只能指向一个变量,从一而终(专一);
-
对引用赋值,是对其指向的变量赋值,而不是修改引用本身的值;
-
对引用做运算,就是对其指向的变量做运算,而不是对引用本身做运算;
-
引用类型就是一个弱化了的指针;个人理解:引用类型就是一个*p。
C++设计引用类型是因为指针类型很难驾驭,一旦用不好就回出问题,所以取长补短设计了引用类型。
那么引用类型在实际开发中的作用是什么呢?我们可以用在函数参数传递中:
#include <stdio.h>
void
Plus(
int
& i) {
i++;
return
;
}
void
main() {
int
i =
10
;
Plus(i);
printf(
"%d \n"
, i);
return
;
}
如上代码中Plus函数的参数是一个引用类型,当我们把变量i传递进去,i就会自增1,而实际上也就修改变量i本身的值;换一种说法就是,我们之前函数参数传递的是值,而这里传递的是变量的地址。
那么在构造类型中又是怎么样的呢?
#include <stdio.h>
class
Base {
public
:
int
x;
int
y;
Base(
int
a,
int
b) {
this
->x = a;
this
->y = b;
}
};
void
PrintByRef(Base& refb, Base* pb) {
printf(
"%d %d \n"
, pb->x, pb->y);
printf(
"%d %d \n"
, refb.x, refb.y);
}
void
main() {
Base b(
1
,
2
);
PrintByRef(b, &b);
return
;
}
我们可以看见除了读取的表现形式不一样,实际上汇编代码是一模一样的;但是指针类型是可以重新赋值并运算的,而引用类型不可以。
当一个变量是int类型的,而我们引用类型却是一个其他类型的,会怎么样呢?
int
x =
10
;
Person& ref = (Person&)x;
这是可以编译的,但是没有实际意义,所以在使用引用的时候原来是什么类型就应该使用什么类型。
大家都知道,我们使用指针的时候是可以修改指针本身的,这会存在一定的风险,而C++中提供了引用类型,不可以修改引用本身,我们可以修改被引用的值,当我们不想其他人修改引用类型对应引用的值,可以使用const这个关键词,这种方式我们称之为常引用:
标签:逆向,int,C++,引用,printf,类型,ref,指针 From: https://www.cnblogs.com/bonelee/p/17299988.html