• C++ 之引用


    1. int argc ,char * argv[] - argument count & argument vector

      argc - 命令行参数个数,argv[]依次指向每一个命令行参数,其中argv[0]为程序名字:下面的程序包含了完整的程序路径。

      #include <iostream>
      
      int main(int argc, char *argv[])
      {     int i = 0;                 // begin with 0
            while (i < argc)
                std::cout << argv[i++] // output string
                     << " "            // output SPACE
                     << std::endl;     // terminate output line 
            return 0;
      }

    引用

    1)作为返回值,不需要产生临时对象,然后拷贝这个对象,(见下面代码的注释),目前不要深究引用机制,目前记住的返回引用的场景:输入流、 //发现其他的再补充

        // 2019-11-24日更新,对于引用作为返回值类型,可以通过汇编可知返回的是结果的地址值(引用视为弱化指针).在C++语法层面上考虑,就是首先,这个函数可以作为左值,是可以赋值的,如在重载[](下标索引)的时候,返回非应用是查值,返回引用,则可以进行赋值.其次,根据上面的说明,返回类型为引用的函数的一大作用就是给函数作用域外的值赋值.这个作用在我这个例子中几乎体现不出来,这是以前总结的时候忽略的,所以在此说明.

    1. #include    <iostream>
      using namespace std;
      
      
      int & rfun(int &);                                                     //don't dig more,ref func saves time.
      int fun(int);
      
      void  main(void) {
          int  a = 7, b = 9; 
          int &ra = a, &rb = b;                                          //Treat ra as another name of a
          int *pa = &ra, *pb = &rb;
      
          cout << pa << "  " << (void *)pa << endl;
          cout << pb << "  " << (void *)pb << endl;
      
          cout << a << "  " << b << endl;
          cout << rb << "  " << (void *)&rb << endl;                      //&rb == pb always.
          rb = rfun(ra);                                 //b=ra;  rb=ra;  -->  int &rd=a;
                                                      //rb=fun(ra);
          cout << rb << "  " << (void *)&rb << endl;
      
          cout << a << "  " << b << endl;
          rb = 8;
          cout << a << "  " << b << endl;
      }
      
      int & rfun(int & r) {
          return  r;        //  b=fun(a)  -->  b=a;
      };
      
      int fun(int r) {
          return    r;        //  b=fun(a)  -->  r=a;  b=r;
      };
      2)引用类型参数

      对于class,vector等类型的参数,引用 避免了值拷贝,提升效率,使用引用,函数可以改变实参的值,如果在调用过程中实参值不会发生变化,那么添加 const 修饰。

             

    //call by ref can change the value after func called.
    #include    <iostream>
    
    using    namespace    std;
    
    void  funr(const int &, int);
    int&  rfun(const int &, int);
    
    void  main(void) {
        int a = 100;
        int& b = a;
        const  int& c = 20;
    
        const int & ca = a;
    
        a = 200;
    
        const int cb = 300;
    
        cout << &a << "  " << a << endl;
        cout << &b << "  " << b << endl;
        cout << &c << "  " << c << endl;
    
        cout << endl << endl;
    
        funr(a, a);                           //first a,like above;second a, int tmp = a;
        funr(2, 2);
        cout << endl << endl;
    
        int& rf = rfun(c, c);
        cout << &rf << "  " << rf << endl;
    
    }
    
    void  funr(const int &  ra, int  pa) {    
        cout << &ra << "  " << ra << endl;
        cout << &pa << "  " << pa << endl;    //int tmp = pa, &pa is addr of tmp
    }
    
    int&  rfun(const int &  ra, int  pa) {    // b = rfun(ra,pa)-->b = ra
    
        int  x = 200, &d = x;
        cout << &ra << "  " << ra << endl;
        cout << &pa << "  " << pa << endl;
        return  (int&)ra;
    }

     以上则是目前想到的关于引用的知识点小结,以前曾经写过这话题的博文,今天讲解细致些,看注释,运行程序,更快速理解引用,VS2015社区版。

     2016-5-21补充代码如下:

    #include    <iostream>
    using namespace std;
    
    
    class    A {
    public:
        int    a;
        A(int = 0);
        A(const    A &);
        A&    operator =    (const    A &);
    
        void    PV(A);
        void    PR(A&);
        A        RV(void);
        A&        RR(void);
    };    //    A
    
    A::A(int x) : a(x) { cout << "Constructor (value)" << endl; }
    A::A(const    A & x) { cout << "Constructor (copy)-" << (void *)&x << endl;    a = x.a; }
    
    A&    A::operator =    (const    A & x) { cout << "Operator (=) @ " << (void *)&x << endl;    a = x.a;    return *this; }
    
    void    A::PV(A x) { cout << "Calling By Value @ " << (void *)&x << endl; }
    void    A::PR(A &x) { cout << "Calling By Refe. @ " << (void *)&x << endl; }
    
    A        A::RV(void) { cout << "Calling Rt Value" << endl;    return    *this; }
    A&        A::RR(void) { cout << "Calling Rt Refe." << endl;    return    *this; }
    
    int main(void) {
        A    oa, ob(3);
    
        cout << "oa @ " << (void *)&oa << endl;
        cout << "ob @ " << (void *)&ob << endl;
    
    
        cout << endl << "00000000000000000000000000000" << endl;
        oa.PR(ob);
        cout << endl << "11111111111111111111111111111" << endl;
        oa.PV(ob);
        cout << endl << "22222222222222222222222222222" << endl;
    
        ob = oa.RR();
        cout << endl << "33333333333333333333333333333" << endl;
    
        ob = oa.RV();
        cout << endl << "44444444444444444444444444444" << endl;
            return 0;
    }

    参数类型为class且为值传递的时,先调用对象的拷贝构造函数生成中间值,然后传入这个中间值到函数中;返回类型为值类型的时,会调用拷贝构造函数生成中间值,实际上返回的是这个中间值。

  • 相关阅读:
    linux的redis的安装和使用
    在linux上安装Mysql和使用
    linux的python3的安装
    linux的优化和命令
    LeetCode 542. 01 Matrix
    Qt keyPressEvent
    QOpenGLTexture 两个纹理叠加
    Qt5.6.0+OpenGL 纹理贴图首战告捷
    更改Qt Application为 Qt Console Application
    Learning part-based templates from large collections of 3D shapse CorrsTmplt Kim 代码调试
  • 原文地址:https://www.cnblogs.com/hanxinle/p/5507136.html
Copyright © 2020-2023  润新知