What
引用是什么?
每个人小时候都有“小名”、“奶名”,例如“狗蛋”“妞妞”之类的,父母喊你的小名跟喊你户口本上的名字效果是一样的,实际上喊小名比较多一点,你也知道“狗蛋”“妞妞”是你而不是别人。
引用不是新定义的一个变量,而是给已存在变量取了一个别名,编译器并不会为引用变量开辟内存空间,他和他引用的变量共同享用同一块内存。
类型&引用变量名 = 引用实体;
void main()
{
int a = 10;
int& ra = a;
int ar[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(&br)[10] = ar;
int* p = &a;
int*& q = p;
}
这下应该很容易就能理解引用了。
注意:
①不能空引用,也就是说引用在定义时必须初始化;
②一个变量可以有多个引用,比如int a = 10;int &ra = a; int&rra = a;
③引用一旦引用了一个实体,就不能再引用其他实体;
④引用变量名的类型和实体类型必须保持一致;
How
一、做传递参数
不仅能做函数的参数,而且效率远高于传值调用。
struct Test{
int ar[100000];
};
void fun1(Test t)//传址调用
{
}
void fun2(Test &t)//传引用
{
}
Test t;
void TestValueTime()
{
time_t begin = clock();
for (int i = 0; i < 10000; ++i)
fun1(t);
time_t end = clock();
cout << "value time : " << end - begin << endl;
}
void TestRefTime()
{
time_t begin = clock();
for (int i = 0; i < 10000; ++i)
fun2(t);
time_t end = clock();
cout << "ref time : " << end - begin << endl;
}
void main()
{
TestValueTime();
TestRefTime();
}
可见传引用效率高于传值,如果结构更复杂,则效率更高。
↑why?
因为以值作为参数或者返回值类型时,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参挥着返回变量的一份临时拷贝,因此用值作为参数或者返回值类型,效率不高。
二、做返回值
先给出普通函数返回和引用返回的区别:
效率比较
struct Test{
int ar[100000];
};
Test t;
Test fun1()
{
return t;
}
Test& fun2()
{
return t;
}
void TestValueTime()
{
time_t begin = clock();
for (int i = 0; i < 10000; ++i)
fun1();
time_t end = clock();
cout << "value time : " << end - begin << endl;
}
void TestRefTime()
{
time_t begin = clock();
for (int i = 0; i < 10000; ++i)
fun2();
time_t end = clock();
cout << "ref time : " << end - begin << endl;
}
int main()
{
TestValueTime();
TestRefTime();
return 0;
}
总结一下:无论是把引用作为参数还是返回值,效率都会提升。
引用和指针的区别
在语法概念上引用是别名,无独立空间,和其引用的实体共享一块空间;
在底层实现上(汇编角度)实际是有空间的,因为引用是按照指针方式来实现的。(俺也不是很理解这句话)
看代码:
查看汇编代码:
引用与指针的不同点:
引用定义时必须初始化而指针不需要;
引用一个实体后不能再引用别的实体,而指针可以在任何时候指向同类型的实体;
不能空引用,但有空指针;
sizeof中,引用为引用实体类型的大小,指针在32位系统下是占4个字节,64位系统下占8个字节;
引用自加即引用实体加一,指针自加为向后偏移一个类型大小;
不能多级引用,但有多级指针;
引用更安全。
谢谢各位大佬常踩!