- 引用可以看作一个已定义变量的别名。
// 引用
#include <iostream>
using namespace std;
int main(void)
{
int a = 10; //c编译器分配4个字节内存, a内存空间的别名
int& b = a; //b就是a的别名
a = 11; //直接赋值
cout << "a=" << a << ",b=" << b << endl;
cout << "--------------" << endl;
int* p = &a;
*p = 12;
cout << "a=" << a << ",b=" << b << endl;
cout << "--------------" << endl;
b = 14;
cout << "a=" << a << ",b=" << b << endl;
cout << "--------------" << endl;
int& c = a; //一个变量可以有多个引用
int& r = a;
int& r = b; //错误,不可更改原有的引⽤关系
float& rr = a; //错误,引⽤类型不匹配
int& ra = r; //可以。对引⽤更次引⽤,表⽰ a 变量有两个别名,分别是 r 和 ra
return 0;
}
- 引用作为函数参数
普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化。
// 引用作为函数参数
#include <iostream>
using namespace std;
struct teacher
{
int id;
char name[64];
};
void print1(struct teacher t1) //t1和t是两个不同变量,
{
cout << "1,id=" << t1.id << endl;
t1.id = 11; //只修改t1,不修改t
}
void print2(struct teacher * t2)
{
cout << "2,id=" << t2->id << endl;
}
void print3(struct teacher& t3) //t3是t的别名,相当于修改了t
{
cout << "3,id=" << t3.id << endl;
}
int main(void)
{
teacher t = { 23,"haha" };
print1(t);
print2(&t);
print3(t);
return 0;
}
- 引用的意义
1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针
2)引用相对于指针来说具有更好的可读性和实用性
//void swap(int a, int b); //⽆法实现两数据的交换
//void swap(int* p, int* q); //开辟了两个指针空间实现交换
#include <iostream>
using namespace std;
void swap(int& a, int& b)
{
int tmp;
tmp = a; a = b;
b = tmp;
}
int main()
{
int a = 3, b = 5;
cout << "a=" << a <<" "<< "b=" << b << endl;
swap(a, b);
cout << "a=" << a << " "<< "b=" << b << endl;
return 0;
}
-
引用的本质
引用所占大小与指针相同
引用在C++中的内部实现是一个常指针 -
引用作为函数的返回值和左值
#include <iostream>
using namespace std;
int getA1()
{
static int a;
a = 11;
return a;
}
int& getA2()
{
int a;
a = 22;
return a; //int &temp = a;
}
int& getA2_static()
{
static int a;
a = 220;
return a;
}
int& getA2_static_interest()
{
static int a = 220;
return a;
}
int main(void)
{
int a1 = 0;
int a2 = 0;
//值拷⻉
a1 = getA1();
//将⼀个引⽤赋给⼀个变量,会有拷⻉动作
a2 = getA2(); //a2=temp;
//int& a3 = getA2(); //错误。我也不是很明白。getA2()中的局部被回收了。由于是栈的引⽤,内存⾮法。
int& a3 = getA2_static(); //正确。将⼀个引⽤赋给另⼀个引⽤作为初始值,由于是静态区域,内存合法
int a4 = getA2_static();
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "a3 = " << a3 << endl;
cout << "a4 = " << a4 << endl;
getA2_static() = 100; //函数返回值是⼀个引⽤,并且当左值
int a5 = getA2_static();
cout << "a5 = " << a5 << endl; //????? 修改不成功
getA2_static_interest() = 100; //函数返回值是⼀个引⽤,并且当左值
int a6 = getA2_static_interest();
cout << "a6 = " << a6 << endl; //????? 修改成功
return 0;
}
- 指针引用
#include <iostream>
using namespace std;
struct Teacher
{
char name[64];
int age;
};
//在被调⽤函数 获取资源
int getTeacher(Teacher** p)
{
Teacher* tmp = NULL;
if (p == NULL)
{
return -1;
}
tmp = (Teacher*)malloc(sizeof(Teacher));
if (tmp == NULL)
{
return -2;
}
tmp->age = 33;
// p是实参的地址 *实参的地址 去间接的修改实参的值
*p = tmp;
return 0;
}
//指针的引⽤ 做函数参数
int getTeacher2(Teacher*& myp)
{
//给myp赋值 相当于给main函数中的pT1赋值
myp = (Teacher*)malloc(sizeof(Teacher));
if (myp == NULL)
{
return -1;
}
myp->age = 36;
return 0;
}
void FreeTeacher(Teacher* pT1)
{
if (pT1 == NULL)
{
return;
}
free(pT1);
}
void FreeTeacher2(Teacher*& myp)
{
if (myp == NULL)
{
return;
}
free(myp);
myp == NULL;
}
int main(void)
{
Teacher* pT1 = NULL;
//1 c语⾔中的⼆级指针
getTeacher(&pT1);
cout << "age:" << pT1->age << endl;
FreeTeacher(pT1);
//2 c++中的引⽤ (指针的引⽤)
//引⽤的本质 间接赋值后2个条件 让c++编译器帮我们程序员做了。
getTeacher2(pT1);
cout << "age:" << pT1->age << endl;
FreeTeacher(pT1);
return 0;
}
- const引用
const 引用的目的是,禁止通过修改引用值来改变被引用的对象。
const 引用有较多使用。它可以防止对象的值被随意修改。因而具有一
些特性。
1、const 对象的引用必须是 const 的,将普通引用绑定到 const 对象是不
合法的。 这个原因比较简单。既然对象是 const 的,表示不能被修改,引用当然
也不 能修改,必须使用 const 引用。实际上,
const int a=1;
int &b=a;
这种写法是不合法 的,编译不过。
2、const 引用可使用相关类型的对象(常量,非同类型的变量或表达式)初
始化。 这个是 const 引用与普通引用最大的区别。
const int &a=2;
是合法的。
double x=3.14;
const int &b=a;
也是合法的。
#include <iostream>
using namespace std;
int main(void)
{
//普通引⽤
int a = 10;
int &b = a;
cout << "b = " << b << endl;
//常引⽤
int x=20;
const int &y = x; //常引⽤是限制变量为只读 不能通过y去修改x了
//y =21; //error
return 0;
}