首页 > 代码库 > 第九章 引用
第九章 引用
第九章 引用
1. 什么是引用?
引用就是别名。int &ra=a;此处的&不是取址运算符,而是引用运算符
3. 引用就是别名常量
4. 引用对象
只能 int &ra=a;// 注意定义引用时要对其初始化
int &ra;
ra=a; //这样是错误的,引用就像常量,只能初始化不能赋值
对象也可以定义一个引用,但是类不能,因为它没有具体的内存地址
5. 空引用
6. 按值传递
按值传递(传递的是副本)≠按地址传递()≠按别名传递(有什么不同?)
9.1.利用指针返回多值
9.2.用引用来返回多值
☆10. 按值传递对象
何时使用复制构造函数:按值传递对象;函数(按值)返回对象;用一个对象初始化另一个对象即复制初始化时;根据元素初始化列表初始化数组元素。这四种情况都将调用复制构造函数。记住,复制构造函数只能用于初始化,不能用于赋值,赋值时不会调用复制构造函数,而是使用赋值操作符。
11. 按址传递对象
(避免调用复制构造函数的方法)
A *func(A *one);
int main()
{
A a;
func(&a);
cout<<func(&a)<<endl;
return 0;
}
A *func(A *one){ return one(地址); }
12. 使用const指针来传递对象
使用const为按址传递提供保护机制(类似实现了值传递的功能)
A const*const func(const A * const one)const{};
const A * const p=func(&a);
a.set(44);
a.set(88);
每个const都有不同意思,还有const不管怎么加都不会修改实参变量的属性(不懂看视频)
int get()const { x=5;return x;}
这里const不能改变成变量的值
13. 按别名来传递对象
所以与指针相比少了两个const
A& b=func(a);//在接受一个对象的别名时被接受方只能是别名,
目的是为了避免调用复制构造函数
//A b=func(a);
14. 到底是使用引用还是指针
这是因为指针可以为空,但是引用不能为空。指针可以被赋值,但是引用只能被初始化。不可以被赋为另一个对象的别名,如果你想使用一个对象记录不同变量的地址,那么你只能使用指针。
指针可以别名不可以
另外,在堆中创建一块内存区域,必须要用指针来指向它,否则这块区域就会变成无法访问的内存空间。当然我们可以用引用来引用指向内存空间的指针。
☆指针与引用的区别:
引用无法delete
int *&r=new int;//功能等价于 int *r=new int 但这样写是有问题的,当new int 返回NULL 别名r就有问题,因为别名不能被赋空,会导致系统崩溃
所以new一个对象是一定要用指针
15. 引用和指针可以一块用
int *r,&ra=a;//只有一个指针
16. 引用容易犯的错误(重新看视频)
17. 引用一个按值返回的堆中对象
//return p后p被释放 但没有delete p 就不能删除p创建的堆中对象
//从而导致这个堆中对象不能再被访问 出现内存泄露
18. 引用一个按别名返回的堆中对象
// r成了空引用 空引用是个隐蔽的杀手要尽量避免
考虑返回的是指针这种情况???
19. 在哪里创建,就在哪里释放
本章总结:
1. 按值传递(传递的是副本)≠按地址传递≠按别名传递
2. 按值传递对象,会调用复制构造函数
按址传递对象,可以避免调用复制构造函数(引用,指针)(记得与const联用)
3. ☆何时调用复制构造函数
① 同类型对象对另一对象的初始化
② 按值传递对象
③ 按值返回对象
④ 初始化顺序容器中的元素
⑤ 根据元素初识化列表初始化数组元素
string strs[]={string(“tonnie”),string(“john”),string(“mark”)};
4. ☆const为按址传递提供保护机制(类似实现了按值传递的功能)
A const * const func(const A * const p)const{}
A const * & func(const A * & r)const{}
5. 指针与引用的区别
① 指针可以为空,引用不可以(p=NULL)
② 指针可以被赋值,引用不可以
③ 指针可以指向堆中空间,用于不可以
④ deldete不能对引用使用
int *&r=new int;//等价于 int *r=new int;
但是,当机子虚拟内存太小,new int会自动返回一个空指针。而引用不能为空(非常规型),所以会导致系统崩溃
6. ☆int* r,&ra=a; //只有一个指针
7. new和delete最好在一个函数体内(为了避免指针混淆,最好在哪创建在哪释放)