引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。
比如:孙悟空,有人叫弼马温,也有人称为齐天大圣。
类型& 引用变量名(对象名) = 引用实体;
- void TestRef()
- {
- int a = 10;
- int& ra = a;//<====定义引用类型
- printf("%p\n", &a);
- printf("%p\n", &ra);
- }
注意:引用类型必须和引用实体是同种类型的
指针和引用,赋值或初始化,权限可以缩小,但是不能放大
- void TestConstRef()
- {
- const int a = 10;
- //int& ra = a; // 该语句编译时会出错,a为常量
- const int& ra = a;
- // int& b = 10; // 该语句编译时会出错,b为常量
- const int& b = 10;
- double d = 12.34;
- //int& rd = d; // 该语句编译时会出错,类型不同
- const int& rd = d;
- }
- void Swap(int& left, int& right)
- {
- int temp = left;
- left = right;
- right = temp;
- }
- int& Count()
- {
- static int n = 0;
- n++;
- // ...
- return n;
- }
注意:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
- #include
- #include
- using namespace std;
-
- struct A { int a[10000]; };
- void TestFunc1(A a) {}
- void TestFunc2(A& a) {}
- void TestRefAndValue()
- {
- A a;
- // 以值作为函数参数
- size_t begin1 = clock();
- for (size_t i = 0; i < 100000; ++i)
- TestFunc1(a);
- size_t end1 = clock();
- // 以引用作为函数参数
- size_t begin2 = clock();
- for (size_t i = 0; i < 100000; ++i)
- TestFunc2(a);
- size_t end2 = clock();
- // 分别计算两个函数运行结束后的时间
- cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
- cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
- }
-
- int main()
- {
- TestRefAndValue();
- return 0;
- }
运行结果:

- #include
- struct A { int a[10000]; };
- A a;
- // 值返回
- A TestFunc1() { return a; }
- // 引用返回
- A& TestFunc2() { return a; }
- void TestReturnByRefOrValue()
- {
- // 以值作为函数的返回值类型
- size_t begin1 = clock();
- for (size_t i = 0; i < 100000; ++i)
- TestFunc1();
- size_t end1 = clock();
- // 以引用作为函数的返回值类型
- size_t begin2 = clock();
- for (size_t i = 0; i < 100000; ++i)
- TestFunc2();
- size_t end2 = clock();
- // 计算两个函数运算完成之后的时间
- cout << "TestFunc1 time:" << end1 - begin1 << endl;
- cout << "TestFunc2 time:" << end2 - begin2 << endl;
- }
- int main()
- {
- TestReturnByRefOrValue();
- return 0;
- }
运行结果

通过上述代码的比较,发现传值和指针在作为传参以及返回值类型上效率相差很大。