C++引用,内联函数,函数重载二义性总结_C++

1.引用

   1.1 引用的概念

   C++语言中,可以定义“引用”。引用定义如下:

   类型名 & 引用名 = 同类型的某变量名;

   例如:int n;

       int &r=n;//r就是一个引用,可以说r的类型是int &,r引用了变量n,或者说r成为n的引用。

   某个变量的引用和这个变量是一回事,相当于该变量的一个别名。请注意,定义引用时一定要将其初始化,否则编译不会通过,通常会用某个变量去初始化引用,初始化后,它就一直引用该变量,不会再引用别的变量了。也可以用一个引用去初始化另一个引用,这样两个引用就引用同一个变量了。不能用常量初始化引用,也不能用表达式来初始化引用(除非该表达式的返回值是某个变量的引用)。总之,引用只能引用变量。

   类型为T &的引用和类型为T的变量是完全兼容的,可以互相赋值。

   引用的示例程序如下:

  1.    #include <iostream>
  2.    using namespace std;
  3.    int main()
  4.    {
  5.       int n=4;
  6.       int &r=n;      //r引用了n,从此r和n就是一回事
  7.       r = 4;        //修改r就是修改n
  8.       cout<<r<<endl;   //输出4
  9.       cout<<n<<endl;   //输出4
  10.       n = 5;        //修改n就是修改r
  11.       cout<<r<<endl;   //输出5
  12.       int &r2 = r;    //r2和r引用同一个变量n
  13.       cout<<r2<<endl;  //输出5
  14.       return 0; 
  15.     }

  1.2 引用作为函数的返回值

    函数的返回值可以是引用,例如下面的程序:

  1.     #include <iostream>
  2.     using namespace std;
  3.     int n = 4;
  4.     int & Setvalue()
  5.     {
  6.         return n;    //返回对n的引用
  7.      }
  8.     int main()
  9.     {
  10.         Setvalue()=40;   //返回值是引用的函数调用表达式,可以作为左值使用
  11.         cout<<n<<endl;   //输出40
  12.         int &r = Setvalue();
  13.         cout<<r<<endl;   //输出40
  14.         return 0;
  15.       }

   1.3 参数传值

      “传值”是指函数的形参是实参的一个拷贝,在函数执行过程中形参的改变不会影响到实参。请看例子:

  1.       #include <iostream>
  2.       using namespace std;
  3.       void Swap(int a,int b)
  4.       {
  5.           int temp;
  6.           temp=a;
  7.           a=b;
  8.           b=temp;
  9.           cout<<a<<b<<endl;
  10.        }
  11.        int main()
  12.         {
  13.           int a=4,b=5;
  14.           Swap(a,b);
  15.           cout<<a<<b<<endl;
  16.           return 0;
  17.          }

  上面的程序的输出结果为:

  5 4 

  4 5

  说明在Swap函数内部,形参a,b的值的确发生了互换,但是在main中的a,b还是维持原来的值,也就是说形参的改变不会影响实参。

  1.4 参数传引用

    在传引用的方式下,形参是对应的实参的引用,也就是说,形参和对应的实参是一回事,那么形参的改变就会改变实参的值。例如:

  1.     #include <iostream>
  2.     using namespace std;
  3.     void Swap(int &a,int &b)
  4.     {
  5.       int tmp;
  6.       tmp = a;a = b;b = tmp;
  7.       }
  8.     int main()
  9.     {
  10.       int n1=100,n2=50;
  11.       Swap(n1,n2);
  12.       cout<<n1<<n2<<endl;   //输出50 100
  13.      }

    进入Swap函数以后,a引用了n1,b引用了n2,a,b的改变会影响到n1,n2的值的改变。

2. 内联函数

    使用函数可以减少代码的体积,但是也带来了运行时间的开销,如果一个函数内部的语句非常的少,执行的时间本来就很短,那么调用这个函数的时间就不能忽略,在C++语言中,“inline”很好的解决了函数调用开销的问题。加了“inline”的函数就叫内联函数,例如:

    inline int max(int a,int b);

    加了inline的作用是相当于在编译的时候将函数的语句代码插入到调用的地方,减少了给变量分配空间后的存取时间,但是inline只是适合短小的函数,对于语句比较多的函数,如果用了inline,相当于付出让体积增加几倍的代价,但是速度只是提高了万分之一,得不偿失,有时候函数看上去很简单,但是包含的循环要用很多次,要消耗大量的时间,也不适合用内联函数。所以内联函数的特点是代码简单,执行很快。

3.函数的重载

    C++语言不允许变量重名,但是允许多个函数取相同的名字,只要参数表不同就可以,这称为函数的重载。相当于同一个事物完成不同的功能。

    那么在调用同名函数的时候,编译器怎么世道调用哪一个函数呢?很简单,编译器通过函数调用语句中实参的个数和类型来判断。因为重载函数的参数表不同,只要调用函数的语句给出的实参和参数表匹配就调用。例如:

  1.     #include <iostream>
  2.     using namespace std;
  3.     int max(int a,int b)
  4.     {
  5.      cout<<max1<<endl;
  6.      }
  7.     double max(double a,double b)
  8.     {
  9.      cout<<max2<<endl;
  10.      }
  11.     double max(double a,double b,double c)
  12.     {
  13.      cout<<max3<<endl;
  14.      }
  15.     int main()
  16.     {
  17.       max(3,4);      //调用int max(int ,int)
  18.       max(2.4,6.0);    //调用double max(double ,double)
  19.       max(1.2,3.4,5);   //调用double max(double ,double, double)
  20.       max(1,2,3);      //调用double max(double ,double, double)
  21.       max(3,1.5);     //二义性!!!!!!!
  22.       return 0;
  23.      }

  二义性分析:在第21行中,编译器调用int max(int ,int),只要将1.5进行强制的转换即可,调用double max(double , double)也可以,此时编译器不知道调用哪一个函数,因此出现了二义性。

  在两个函数同名而且参数个数不同,但是其中参数多的那个函数的参数又可以默认的情况下,也可能发生二义性,例如:

  int sum(int a,int b,int c=0);

  int sum(int n,int m);

  此时调用:

  sum(1,2);

  此时的编译器不知道是应该以(1,2,0)作为参数调用第一个函数还是以(1,2)调用第二个函数,产生了二义性!

posted on 2017-09-12 21:25  show_me_the_code  阅读(813)  评论(0编辑  收藏  举报

导航