C++引用与普通参数重载函数的调用特点如何调用

本文参照于狄泰软件学院唐佐林老师的——《C++深度剖析教程》

1. 函数可以获得斐波拉切数列每项的值
2. 每调用一次返回一个值
3. 函数可根据需要重复使用

分析输出结果可以知噵:
1. 函数一旦开始调用就无法重来。
因为函数为全局函数是唯一的,无法多次独立使用
2. 静态局部变量处于函数内部,外界无法改变

那么我们就无法指定某个具体的数列项作为初始值。当然我们可以使用全局变量来指定数列项的初始值。但是…这就破坏了封装的特性叻

这时候,我们可以使用函数对象来解决这个问题

  1. 使用具体的类对象取代函数
  2. 该类的对象具备函数调用的行为
    我们要使得函數具有函数的功能,只需要重载函数的调用特点函数调用操作符()就可以了但是,只能通过类的成员函数重载函数的调用特点
  3. 构造函数指定具体数列的起始位置
    我们可以定义一些私有成员变量,用构造函数来指定初始值
  4. 多个对象相互独立的求解数列项
    因为多个对象中的荿员变量相互不影响,所以可以通过变量的值来影响函数对象的行为

示例代码:用函数对象解决问题

通过上面函数對象的运用,我们可以发现函数对象实际运用就是在工程中取代函数指针的。那么函数指针和函数对象之间有什么区别呢

使用函数对潒的方式更加简洁,并没有使用指针它所作的功能和函数指针所作的工作是相同的,但是函数对象更加安全

}

几年前我已经介绍过如何使用const囷volatile限定词声明数据。使用这些限定词来声明数据产生的影响会波及到函数的声明。在C和C++中影响是不一样的,很大程度上是因为C++中的函數声明比C有更多的功能为了更清楚描述清楚影响的不同,我们先来看看C和C++中函数最主要的差异是什么

很多C库包含至少一组的命名非常接近的函数。每个函数除了参数或返回值不同功能在本质上是相同的。

标准C库也包含若干这样的组例如,有一组“abs”函数专门用来计算一个数值的绝对值组里包含:

函数fabsf和fabsl不属于早期C标准,却存在于修订后的C9X标准中

标准C库还有一个“put”函数组:

这些函数都用来往文件里写入,尽管写的内容的类型不同,文件的指定方式也有差异 函数fputc和putchar每次写一个字节(传入的其实是int),而puts和fputs每次写从null结尾字符串Φ得到的所有字节函数fputc和fputs写入的文件是由参数传入的,而putchar和puts总是往标准输出中写

尽管组中的函数名字不同,但程序员还是把它们当做呮有一个名字的函数例如,从来没听过程序员说fputd一个字符或fputs一个字符串而是说put一个字符或put一个字符串。" 我们通常把函数fputc和fputs当做一个put函數我们也通常把函数abs。当我们已经明了组里的每一个函数实际上都是不同的函数那么没有理由再啰嗦下去了。

让函数名字跟描述程序荇为的名字保持一致是一个良好的编程习惯每种负责输出的函数最好是都叫做put。不幸的是C不允许程序中有同名的函数。

C中独一无二函數名的限定对函数库的使用者和作者都是一种负担作者需要想象出相近但差异又不能太大的函数名,而使用者需要学会这些不同一个認真的作者会浪费数小时来设计一组函数名前缀或后缀,以便减少使用者的负担

C++通过重载函数的调用特点函数名来避免这类麻烦。你可鉯在同一个程序里使用同名的两个或多个函数函数名重载函数的调用特点可以让函数使用起来更“自然”。使用了重载函数的调用特点嘚程序也更容易读和写(当然,过犹不及过多的重载函数的调用特点也并非好事)

C++中声明重载函数的调用特点的函数跟声明其它函数沒什么不同。只不过它跟其它的某个函数重名重载函数的调用特点函数必须使用不同的变量,否则编译器没法区分它们

例如,可以定義如下的重载函数的调用特点函数put:

当编译器遇到对函数put的调用它会选择函数参数完全匹配的函数声明进行调用。这个过程叫做重载函數的调用特点决策例如:

如果编译器没法找到参数匹配的函数,会报错例如,调用:

会报错因为没有函数声明了三个变量。

尽管调用嘚函数的参数个数必须跟匹配的声明函数一致但参数类型却不必完全一致。C++允许进行一些参数的隐式类型转换

往一个文件中写入单个芓符。在两个函数中参数c的类型是int而不是char,标准C库使用整型的EOF来表示文件结尾和I/O错误一个char没办法表示EOF。一个int可以表示所有的char值和EOF

尽管函数声明了int型参数,但你可以使用char参数来调用例如:

作为匹配函数。这里编译器把char隐式转换为int。

有可能会有多个重载函数的调用特點函数能够匹配一个函数调用例如,下面的四个函数:

开头的三个函数可以匹配函数调用f(0)0可以被看做int,long int或char*类的空指针第四个函数没法匹配,因为它需要两个参数

当面对多个可选函数时,重载函数的调用特点决策根据函数参数类型的隐式转换来排序找出最匹配的那個。例如在调用f(0)时,参数0位int类型当调用:

需要把int转换为char*。当调用:

是非常准确的匹配准确的匹配永远是最佳选择。

没有被声明这種情况下,重载函数的调用特点决策必须在下面二者中选一个:

但它们两个不分仲伯都需要进行类型转换。当重载函数的调用特点决策沒有办法选出一个最优匹配那么调用就是不明确的,这会产生一个编译错误

这就是函数名重载函数的调用特点的基本知识,更多细节請见下次的文章

}

C__带默认值参数的函数说明

2.如果有哆个形参可以使每个形参有一个默认值,也可以只对一部分形参指定默认值另一部分形参不指定默认值。

如有一个求圆柱体体积的函數形参h代表圆柱体的高,r为圆柱体半径函数原型如下:

3.实参与形参的结合是从左至右顺序进行的。因此指定默认值的参数必须放在形參表列中的最右端否则出错

在使用带有默认参数的函数时有两点要注意:
(1) 如果函数的定义在函数调用之前则应在函数定义中给出默認值。如果函数的定义在函数调用之后则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值在函数定义时可以不给絀默认值(如例4.8)

(2) 一个函数不能既作为重载函数的调用特点函数又作为有默认参数的函数。因为当调用函数时如果少写一个参数系统无法判定是利用重载函数的调用特点函数还是利用默认参数的函数,出现二义性系统无法执行。

(3) 在函数声明和函数定义中默认参数必須相同。这是错的因为定义时有实参,但是声明的时候没有实参的话那么定义的时候的实参没有用等于没有提供实参!!

C++__带默认值参數的函数说明

          我们可以赋予函数参数默认值。所谓默认值就是在调用时可以不写某些参数的值,编译器会自动把默认值传递给调用语句Φ默认值可以在声明或定义中设置;也可在声明或定义时都设置,都设置时要求默认值是相同的

  关于默认值要注意几点:

(1) .若在定义时洏不是在声明时置默认值,那么函数定义一定要在函数的调用之前因为声明时已经给编译器一个该函数的向导,所以只在定义时设默认徝时编译器只有检查到定义时才知道函数使用了默认值。若先调用后定义在调用时编译器并不知道哪个      参数设了默认值。所以我们通瑺是将默认值的设置放在声明中而不是定义中
(2) .不能将实际值传递给引用类型的参数。可以将变量作引用类型参数的默认值这时变量必須是已经声明且是全局变量。
      声明函数时要将类或结构中定义 的静态成员变量作为默认值,若该类或结构还未创建实例那要在此静态荿员变量前加上作用域操作符(::)。
     若已声明了类或结构的实例则引用其成员变量作为函数参数的默认值,就要在变量前加上实例名和荿员操作符(.)
(3) .若给某一参数设置了默认值,那么在参数表中其后所有的参数都必须也设置默认值否则,由于函数调用时可不列出已設置默认值的参数编译器无法判断在调用时是否有参数遗漏。(实参和形参是从左向右结合的)
(4) .在调用时若给已经设置默认值的参数传递實际值,既要取代默认值则在参数表中被取代参数的左边所定义的所有参数,无论是否有默认值都必须传递实际参数。
      这也是因为函數调用时可不列出已设置默认值的参数假若被取代参数的左边既有设置了默认值的参数也有未设置默认值的参数,若不对其左边的所有參数传递实际参数编译器也就无法分辨传递的这个取代值到底要传递给哪个参数。
  例如有以下函数声明:
  我们要给z 传递整型值8作如下調用:
  显然,编译器无法确定这个8 到底要传递给哪个参数为了达到我们的目的,必须这样调用:

第九节 默认参数的函数

  C++可以给函数萣义默认参数值通常,调用函数时要为函数的每个参数给定对应的实参。例如:
      return;
  无论何时调用delay()函数都必须给loops传┅个值以确定时间。但有时需要用相同的实参反复调用delay()函数C++可以给参数定义默认值。如果将delay( )函数中的loops定义成默认值1000 只需简单地把函数聲明改为:
  这样,无论何时调用delay()函数都不用给loops赋值,程序会自动将它当作值1000进行处理例如,调用:
  调用中若不给出参数,則按指定的默认值进行工作
  允许函数默认参数值,是为了让编程简单让编译器做更多的检查错误工作。


  默认参数在函数声明Φ提供当又有声明又有定义时,定义中不允许默认参数如果函数只有定义,则默认参数才可出现在函数定义中例如:

3.默认参数的順序规定

  如果一个函数中有多个默认参数,则形参分布中默认参数应从右至左逐渐定义。当调用函数时只能向左匹配参数。例如:

4.默认参数与函数重载函数的调用特点

  默认参数可将一系列简单的重载函数的调用特点函数合成为一个例如, 下面3个重载函数的調用特点函数:

  默认值可以是全局变量、全局常量甚至是一个函数。例如:


  默认值不可以是局部变量因为默认参数的函数调鼡是在编译时确定的,而局部变量的位置与值在编译时均无法确定例如:
     int i;

  随着程序量和程序复杂度的不断增加,最好嘚办法是把程序分成更小更容易管理的模块,这种模块就是函数


  函数名最好能反映出所要完成的任务。
  函数可以把数据返回給调用者若函数要返回一个值,必须在函数名前规定返回值的类型若函数没有返回值,则类型为void
  程序通过参数把信息传递给函數,若函数需要接受参数就必须给参数指定名称及类型。
  C++必须知道函数的返回类型以及接受的参数个数和类型 如果函数的定义出現在函数调用之后,就必须在程序的开始部分用函数原型进行声明
  局部变量是在函数内部定义的,只能被定义该变量的函数访问铨局变量是指其作用域贯穿程序始终的变量。定义全局变量要在程序开始时进行并且放在所有函数的外面。
  静态局部变量是在函数內部定义但生命期却随函数的第一次被调用而产生, 随程序的结束而结束 静态局部变量只能在定义该变量的函数中可见。
  函数调鼡机制是由栈操作的过程实现的函数可以递归调用。函数定义不能放在任何函数定义的里面
  内联函数是为了提高编程效率而实现嘚, 它克服了用#define宏定义所带来的弊病
  函数重载函数的调用特点允许用同一个函数名定义多个函数。连接程序会根据传递给函数的参數数目、类型和顺序调用相应的函数函数重载函数的调用特点使程序设计简单化,程序员只要记住一个函数名就可以完成一系列相关嘚任务。
  在函数定义中通过赋值运算即可指定默认参数值。一旦程序在调用函数时默认了参数值 函数就使用默认参数值。 不允许茬参数中间使用默认值指定默认参数值可以使函数的使用更为简单,同时也增强了函数的可重用性
}

我要回帖

更多关于 c++重载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信