一:引用概念---引用就是为一个变量起一个别名
每个变量都是指向一块内存空间的标识,引用就是重新设置一个标识,但是这个标识还是指向同一个内存空间
和指针类似(其实
引用本质就是使用了一个常指针 const int* b; 可修改内存值,不可修改指针地址),都可以直接操作同一块内存但是引用的可读性更好,在一些场合可以代替指针
二:简单使用(同指针一起)
//1.值传递
void swap01(
int a,
int b)
{
int temp =
a;
a =
b;
b =
temp;
}
//2.指针传递
void swap02(
int* a,
int*
b)
{
int temp = *
a;
*a = *
b;
*b =
temp;
}
//3.引用传递
void swap03(
int& a,
int&
b)
{
int temp = a;
//可读性好些
a =
b;
b =
temp;
}
void main()
{
int a1 =
1, b1 =
2;
int a2 =
1, b2 =
2;
int a3 =
1, b3 =
2;
swap01(a1, b1);
swap02(&a2, &
b2);
swap03(a3, b3);
cout <<
"值传递:" << a1 <<
" " << b1 <<
endl;
cout <<
"指针传递:" << a2 <<
" " << b2 <<
endl;
cout <<
"引用传递:" << a3 <<
" " << b3 <<
endl;
system("pause");
return;
}
三:函数返回值涉及引用
(一)当函数返回值为引用(局部变量的引用)
int&
getRef()
{
int a =
10;
cout << &a <<
endl;
return a; //
这是局部变量,一般会在函数结束后被释放栈空间
//但是若是返回的类型是引用,则会将该变量保留 <<重点>>
//类似其他语言中,只有当该内存空间无变量指向时,才会被回收 <<重点>>
//但是返回引用,则说明,将有其他变量指向该内存空间,不允许回收,延长了生命周期 <<重点>>
}
void main()
{
int a = getRef();
//相当于直接传值出来
cout << &a <<
" " << a <<
endl;
int &b = getRef(); //将b指向局部变量a的地址,延长了变量生命周期 //注意使用引用来接收int &b,那么该函数返回类型必须是引用int& getRef
cout << &b <<
" " << b <<
endl;
system("pause");
return;
}
(二)当函数返回值为引用(static变量的引用)
由于static变量的生命周期是当前文件,故不局限于某个函数。
---既可以作为其他引用的初始值,还可以作为左值进行使用
int&
getRef()
{
static int a = 10;
cout << &a <<
endl;
return a;
}
void main()
{
int &b = getRef();
//将b指向局部变量a的地址,延长了变量生命周期
cout << &b <<
" " << b <<
endl;
getRef() = 15; //允许作为左值使用
cout << &b <<
" " << b <<
endl;
system("pause");
return;
}
(三)当函数返回值为引用(返回值是形参) //相当于(一)局部变量,这里用于连接内存和引用
引用归根到底还是对内存的新标识
int& g2(
int*
p)
{
*p =
100;
cout << p <<
endl;
return *
p; //看返回的是一个值,实际该值存放的内存还是和a1内存是一致的,返回的引用地址也就是这个内存地址
}
void main()
{
int a1 =
101;
cout << &a1 <<
" " << a1 <<
endl;
int& a2 = g2(&
a1); //a2指向返回的内存地址引用
cout << &a2 <<
" " << a2 <<
endl;
system("pause");
return;
}
(四)当函数返回值为引用(对象的引用,涉及拷贝构造函数和=操作符重载)---需要补充
四:常引用const
(一)使用变量初始化const引用---会将该 引用变量 变为只读
正常使用
尝试修改局部变量
尝试修改引用变量
(二)常用在为他人提供接口,同C++回顾day01---<const常量重点>
设置变量内存为只读,不允许使用接口的用户进行数据修改,只可以进行数据读取
void ReadOnly(
const int&
a)
{
cout << &a <<
" " << a <<
endl;
//a = 110; //不允许修改
}
void main()
{
int a1 =
100;
ReadOnly(a1);
a1 =
101;
ReadOnly(a1);
}
四:匿名对象引用(重点:https://www.cnblogs.com/ssyfj/p/10627359.html)
class Test
{
private:
int a, b;
public:
Test(int a,
int b)
{
this->a =
a;
this->b =
b;
}
void getInfo()
{
cout << a <<
" " << b <<
endl;
}
};
Test func1()
{
return Test(
1,
2);
//匿名对象1
}
void main()
{
Test T = func1(); //直接将匿名对象用来初始化同类型对象
//会直接将匿名对象设置为这个新的对象
//即匿名对象1没有释放,而是直接变为T对象
cout << &T <<
endl;
T.getInfo();
system("pause");
}
Test&
func2()
{
return Test(
3,
4);
//匿名对象2
}
void main()
{
Test T = func2(); //使用匿名对象来初始化,会直接将匿名对象转变为这个对象T,延长生命周期
T.getInfo();
Test& T2 = func2(); //若是这里T2是一个引用,则不是直接拷贝赋值,
//而是对匿名对象2的内存空间的一个别名,
//而这个对象已经被释放了,故结果是随机值
T2.getInfo();
system("pause");
}
转载于:https://www.cnblogs.com/ssyfj/p/10625188.html