• Essential C++学习笔记


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

    2.Pass by Reference语意

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

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

    当我们这么写:

    1 int jval=4096;
    2 rval=jval; 

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

    1 pi=&rval;

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

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

    1 void swap()
    2 {
    3 //实际参数的值会因而改变
    4 int temp=val1;
    5 val1=val2;
    6 val2=temp;
    7 }

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

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

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

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

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

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

    1 void display(const vector<int> &vec)
    2 {
    3 for(int ix=0;ix<vec.size();++ix)
    4 {
    5 cout<<vec[ix]<<" ";
    6 cout<<endl;
    7 }
    8 }

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

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

     1 void display(const vector <int> *vec)
     2 {
     3       if(!vec) 
     4       {
     5         cout<<"display():the vector pointer is 0\n";
     6         return ;
     7 }
     8 
     9 for(int ix=0;ix<vec->size();++ix)
    10 {
    11        cout<<(*vec)(ix)<<" ";
    12        cout<<endl;
    13 }
    1 int main()
    2 {
    3    int ia[8]={1,2,1,12,2,2,1,1};
    4    vector<int>  vec(ia,ia+8);
    5 
    6    cout<<"vector before sort";
    7    display(&vec);//传入地址
    8    // 其余代码
    9 }

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

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

  • 相关阅读:
    严格模式
    es6模块与 commonJS规范的区别
    Javascript内置对象、原生对象、宿主对象关系
    实现继承的几种方式
    创建对象的一些方式
    null的小扩展
    getElementById的缩略
    你真的知道为什么不推荐使用@import?
    换行与不换行
    transition与animation
  • 原文地址:https://www.cnblogs.com/sggggr/p/9022843.html
Copyright © 2020-2023  润新知