1.当我们调用一个函数时,会在内存中建立起一块特殊区域,称为“程序栈”,这块特殊区域提供了每个函数参数的存储空间,它也提供函数所定义的每个对象的内存空间--我们将这些对象称为局部对象。一旦函数完成,这块内存就会被释放掉,或者是说从程序堆栈中被pop出来。

2.Pass by Reference语意

reference扮演着外界与对象之间的一个间接号码牌的角色,只要在型别名称和reference名称之间插入&符号,便是声明了一个reference:

 int ival=;   //对象,型别为int
int *pi=&ival; //pointer(指针),指向一个int对象
int &rval=ival; //reference(化身),代表一个int对象

当我们这么写:

 int jval=;
rval=jval;

时,便是将jval赋值给rval所代表的对象(也就是ival).我们无法rval改为代表jval,因为C++不允许我们改变reference所代表的的对象,它们必须从一而终,当我们写:

 pi=&rval;

时,我们其实是将ival(此为rval所代表的之对象)的地址赋值给pi.我们并未令pi指向rval.注意,重点是面对reference的所有操作都像面对“reference 所代表之对象”所进行的操作一般无二。当我们以reference作为函数参数时,亦复如此。

当swap()函数将val2赋值给val1:

 void swap()
{
//实际参数的值会因而改变
int temp=val1;
val1=val2;
val2=temp;
}

时,的确是将vec[jx]赋值给vec[ix]--前者是val2所代表的之物,后者是val1所代表的之物:

 swap(vec[ix],vec[jx]);

当我们以by reference 方式传递对象当做函数参数,对象本身并不会复制出另一份——复制的是对象的地址。函数中对该对象进行的任何操作,都相当于是对传入的对象进行间接操作。

将参数声明为reference的理由之一是,希望得以直接对所传入的对象进行修改。这个理由极为重要,因为就像我们在前面的例子中所见,不这么做的话,程序无法正确运行。

将参数声明为reference的第二个理由是,为了降低复制大型对象的负担。这个理由相较起来不那么重要,因为对程序而言不过是效率议题罢了。

3.举个例子,现在我将打算显示的vector以传值方式传入display()中,这意味着每当我想进行显示操作时,vector内的所有元素都会被复制。这并不会造成错误,但是如果直接传入vector地址,速度会更快。将vector的参数声明为reference,便可达到这个目的。

 void display(const vector<int> &vec)
{
for(int ix=;ix<vec.size();++ix)
{
cout<<vec[ix]<<" ";
cout<<endl;
}
}

我们声明了一个 reference to const vector ,因为函数之中并不会更改vector的内容,少了const并不会造成错误,但加上const可以让阅读程序的人了解,我们以传址的方式来传递vector,为的是避免重复操作,而不是为了要在函数之中对它进行修改。

如果我们愿意,也可以将vector以pointer的形式传递。这和以reference传递的效用相同:传递的是对象的地址,而不是整个对象的复制品。唯一的差别在于reference和pointer的用法不同,例如:

 void display(const vector <int> *vec)
{
if(!vec)
{
cout<<"display():the vector pointer is 0\n";
return ;
} for(int ix=;ix<vec->size();++ix)
{
cout<<(*vec)(ix)<<" ";
cout<<endl;
}
 int main()
{
int ia[]={,,,,,,,};
vector<int> vec(ia,ia+); cout<<"vector before sort";
display(&vec);//传入地址
// 其余代码
}

pointer参数和reference 参数二者之间更重要的差异是,pointer可能(也可能不)指向某个实际对象,当我们提领pointer时,一定要先确定其值并非0.至于reference则必定会代表某个对象,所以不需要做此检查。

一般来说,除非你希望在函数内更改参数值,否则在传递内建型别时,不要使用传址方式,传址方式主要是作为传递class object 之用。

Essential C++学习笔记的更多相关文章

  1. Essential C++ 学习笔记02--Array/Vector 与指针

    Essential C++ 1.5-1.6节,3.1节笔记 Array/Vector/指针,难度偏大, 但若学习初期不熟悉基本用法,则难以写出有效代码. 1. 基本概念 Array 是一段连续内存,数 ...

  2. Essential C++ 学习笔记01--基本语法

    <Essential C++>1.1-1.4节笔记 1. main 函数 main 函数是代码的入口,若无 main 函数,编译不通过. main 函数通常声明为 int, return ...

  3. VSTO 学习笔记(十)Office 2010 Ribbon开发

    原文:VSTO 学习笔记(十)Office 2010 Ribbon开发 微软的Office系列办公套件从Office 2007开始首次引入了Ribbon导航菜单模式,其将一系列相关的功能集成在一个个R ...

  4. Essential C#读书笔记

    Essential C#读书笔记 这是一个多变的时代,一次又一次的浪潮将不同的人推上了巅峰.新的人想搭上这一波,同时老的人也不想死在沙滩上.这些年新的浪潮又一次推开,历史不停地重复上演,那便是移动互联 ...

  5. 学习笔记之pandas

    Python Data Analysis Library — pandas: Python Data Analysis Library https://pandas.pydata.org/ panda ...

  6. 【VS开发】VSTO 学习笔记(十)Office 2010 Ribbon开发

    微软的Office系列办公套件从Office 2007开始首次引入了Ribbon导航菜单模式,其将一系列相关的功能集成在一个个Ribbon中,便于集中管理.操作.这种Ribbon是高度可定制的,用户可 ...

  7. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  8. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  9. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

随机推荐

  1. 各种浏览器怎么换ip

    https://jingyan.baidu.com/article/e4d08ffdb784050fd2f60ddd.html 方法/步骤   1 用浏览器搜索ip,得到自己当前的ip. 2 用浏览器 ...

  2. C#的类

    一.String类 1.Length 字符的长度 string x = Console.ReadLine();int i = x.Length;// Length 是获取字符串的长度(从1开始数)Co ...

  3. 在eclipse中建立lua开发环境

    1. 给你的eclipse安装LuaEclipse,新增Eclipse Software Update Site“http://luaeclipse.luaforge.net/update-site ...

  4. JVM堆内存管理与自定义分配参数详解

    堆内存模型: 在Java中,堆被划分成两个不同的区域:新生代(Young),老年代(Old).而Permanent属于永久代(方法区),不属于堆内存.新生代又被分为了三个区域:Eden,from  s ...

  5. P1024 硬币问题

    题目描述 假设现在有面值为1, 5, 10, 50, 100, 500的硬币各无限枚, 如果用这些硬币来支付A元, 最少需要多少枚硬币? 输入格式 一个整数A(0<=A<=1e9), 表示 ...

  6. 使用Python内置的smtplib包和email包来实现邮件的构造和发送。

    此文章github地址:https://github.com/GhostCNZ/Python_sendEmail Python_sendEmail 使用Python内置的smtplib包和email包 ...

  7. linux 禁止单个中断

    有时(但是很少!)一个驱动需要禁止一个特定中断线的中断递交. 内核提供了 3 个函数为 此目的, 所有都声明在 <asm/irq.h>. 这些函数是内核 API 的一部分, 因此我们描述它 ...

  8. ajaxSetup()方法

    使用ajaxSetup()方法设置全局Ajax默认选项 使用ajaxSetup()方法可以设置Ajax请求的一些全局性选项值,设置完成后,后面的Ajax请求将不需要再添加这些选项值,它的调用格式为: ...

  9. dotnet 判断程序当前使用管理员运行降低权使用普通权限运行

    有一些程序是不想通过管理员权限运行的,因为在很多文件的读写,如果用了管理员权限程序写入的程序,其他普通权限的程序是无法直接访问的.本文告诉大家如何判断当前的程序是通过管理员权限运行,然后通过资源管理器 ...

  10. JQ表单选择器和CSS3表单选择器

    JQ表单选择器和CSS3表单选择器 JQ表单选择器 为了使用户能够更加灵活地操作表单,jQuery中加入了表单选择器,利用这个选择器能极其方便的获取到表单的某个或者某类型的元素.表单选择器的介绍如图: ...