马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 moc 于 2018-8-26 22:25 编辑
1、引用的概念
引用是C++的概念,在C中没有引用这个东东,它属于C++编译器对C的扩展。
引用的定义:
Type &name = var; int a = 10;
int &b = a;
b = 20;
cout << a << endl; // 20
int &c = b;
c = 30;
cout << a << endl; //30
int d = c;
d = 50;
cout << a << endl; //30
引用可以看成是一个已经定义好的变量的别名。
引用在定义的时候必须为它绑定变量,而且一旦定义完成,便无法为它重新绑定到另一个的变量。
上面程序中,b、c都是a的引用变量,通过b、c都可以间接修改a的值,可以把b、c看成a的别名。
2、引用的意义
1.引用作为其他变量的别名,可以通过它来间接修改变量的值,在一些场合可以代替指针的存在。
2.引用相较于指针具有更好的可读性和实用性。
通过引用做函数参数,在被调函数中间接修改变量的值,相较于指针可读性更强。
3、引用变量占据内存空间吗?
通过在结构体中定义引用变量来测试:struct Teacher
{
int &a;
int &b;
char &c;
double &d;
};
int main()
{
cout << sizeof(Teacher) << endl; // 16
system("pause");
return 0;
}
可以发现引用本身占据一定的内存空间,具体来说是不管什么类型的引用都占4个字节(32位机),和指针一样。
4、引用的本质
1.引用在C++的内部实现是一个常量指针。
即: Type &name <-----> Type* const name;
2.C++编译器在编译过程中使用常量指针来作为引用的内部实现,它占4字节(32位机)内存空间,一旦初始化后就不能绑定其他变量(常指针其值不能修改,即指向关系不能修改),初始化之后的使用,C++编译器一旦看到是引用变量,便会自动帮我们做*p的操作,这就是我们能用引用间接赋值的原理,同样当我们对引用变量取地址时,C++编译器不会对这个这个常指针取地址,而是把它的值直接输出,即变量的地址。
3.从使用的角度,引用会让人误会其只是变量的一个别名,没有自己的存储空间。这只是C++为了实用性而做出的细节隐藏。
4.引用与间接赋值的三个条件
①定义两个变量(一个实参、一个形参)
②建立关联 => 实参取地址传给形参
③形参通过*p操作去间接修改实参的值
对于引用做函数参数,其实质就是把①放在主调函数中,②③放入被调函数中,且由C++编译器帮我们做了取地址和*p操作。
5、返回引用的函数
函数返回引用时可以看做就是把返回的变量转成(绑定自身)引用变量,再返回。
当函数的返回值为引用时,若函数返回的时栈(局部)变量,不能将其作为其他引用的初始值。
若返回引用时,为静态(static)变量或全局变量时,这该函数即可做左值也可做右值。int& myf() //返回引用,即返回a的地址,引用在使用时会自动做*操作。
{
int a;
a = 12;
return a;
}
void main08()
{
int b1 = myf(); // 使用引用,(隐式*p操作)
int &b2 = myf(); // b2引用初始化, 对返回的引用a取地址,引用a取地址,是其绑定的内存地址
cout << b1 << endl; //12
cout << b2 << endl; // 乱码
system("pause");
}
上面在引用b2初始化时绑定临时变量a,在函数mf()调用结束后,a所在的内存空间被销毁,所以b2会乱码。
6、指针的引用
相当于给指针取别名,和上面的是一样的,不要被其形式所迷惑。struct AdvTeacher
{
char name[32];
int age;
};
// 结构体变量指针的引用
// p2是t2的别名
void getTeacher(AdvTeacher * &p2)
{
p2= (AdvTeacher *)malloc(sizeof(AdvTeacher));
p2->age = 30;
}
int main()
{
AdvTeacher *t2 = NULL;
getTeacher02(t2); // 在被调函数中给t2分配空间
t2->age = 10;
system("pause");
return 0;
}
7、常引用
C++可以声明const 引用:
const Type &nmae = var; //本质 const Type* const name
声明常引用让该引用变量拥有只读属性,也即通过引用变量将不能修改其绑定变量的值,但变量可以通过自身来修改。 int b = 10;
const int &a = b; // 本质const int* const a
// a = 11; // error 不能通过常引用a去间接修改b的值
b = 12; // 本身可以修改
给字面量初始化const引用://int &c = 13; // error 字面量不可初始化引用
const int &c = 13; // 字面量可以初始化常引用
当使用字面量对const引用进行初始化时,C++编译器会为该常值量分配空间,将引用名作为这段空间的别名。
字面量const引用相当于一个只读变量。
|