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)调用第二个函数,产生了二义性!

时间: 2024-10-19 21:48:01

C++引用,内联函数,函数重载二义性总结_C++的相关文章

内联成员函数应放在哪

今天复习C++ Primer的时候,看到了关于C++类的内联成员函数的放置,应该放在头文件中.那么这到底是为什么 呢?仅仅是一种代码规范问题还是必须这样做呢? 下面我就来讲讲我自己的理解吧.要彻底理解这个问题,首先就要了解下函数的声明和定义了.我们知道,函数可以 在多处声明,但只能在一个地方定义,不然就会出现重定义.大部分函数默认是外部链接,而inline函数默认为内部链 接.也就是说inline函数只能在本文件中使用,对其他文件是不可见的.一般我们使用某个类的时候,都是在文件中加 上该类的头文

sql server 创建内联表值函数

表值函数就是返回table 的函数使用它可以方便的进行查询的处理 创建的代码如下: create FUNCTION returunclassfirstlist(  -- Add the parameters for the function here )RETURNS TABLE ASRETURN ( -- Add the SELECT statement with parameter references here select * from classfirst;) 我们在使用创建的函数的时

C++如何处理内联虚函数

http://blog.csdn.net/hedylin/article/details/1775556 当一个函数是内联和虚函数时,会发生代码替换或使用虚表调用吗? 为了弄清楚内联和虚函数,让我们将它们分开来考虑.通常,一个内联函数是被展开的. class CFoo { private: int val; public: int GetVal() { return val; } int SetVal(int v) { return val=v; } }; 这里,如果使用下列代码: CFoo x

内联表值函数FUNCTION

创建一个内联表值函数: 1 USE TSQLFundamentals2008; 2 IF OBJECT_ID('dbo.fn_GetCustOrders') IS NOT NULL 3 DROP FUNCTION dbo.fn_GetCustOrders; 4 GO 5 CREATE FUNCTION dbo.fn_GetCustOrders 6 (@cid AS INT) RETURNS TABLE 7 AS 8 RETURN 9 SELECT orderid, custid, empid,

C++中的内联成员函数与非内联成员函数

在C++中内联成员函数与非内联成员函数的可以分为两种情况: 1.如果成员函数的声明和定义是在一起的,那么无论有没有写inline这个成员函数都是内联的,如下: using namespace std; class test{ public: void fuc() { cout << "ok!" << endl; } }; int main(void) { test t, t1; t.fuc(); t1.fuc(); return 0; } 或者: using n

内联表值函数

内联表值函数是一种可重用的表表达式,能够支持输入参数.除了支持输入参数以外,内联表值函数在其他方面都与视图相似.(可以将内联表值函数看作是一种参数化的视图,尽管没有这种正式的说法). 例: CREATE FUNCTION fn_GetCustOrders (@cid as int) RETURNS TABLE AS RETURN SELECT orderid,custid,empid,orderdate,requiredate FROM dbo.Orders WHERE [email prote

堆(stack) 之 c 和 c++模板实现(空类默认成员函数 初谈引用 内联函数)

//stack 的基本操作 #include <iostream> using namespace std; const int maxn = 3; typedef struct Stack { //NumType num; int num; }Stack; int top = 0;//当前元素位置的上一个元素 Stack stack[maxn]; bool is_empty(); bool is_full(); int pop(); void push(const int &key)

为什么 构造函数、内联函数、静态函数和友元函数不能是虚函数

构造函数为什么不能是虚函数 C++ 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数.简单来说就是:虚函数的执行依赖于虚函数表.而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表.而在构造对象期间,虚函数表还没有被初始化,将无法进行

深入探讨 内联函数和宏定义的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题: 1)内联函数的定义性声明应该出现在