vc程序的使用方法(VC函数重载与函数模板)

C 是一门强类型语言,定义函数时,必须严格声明参数类型和返回值类型。强类型的语言解决同一个函数支持多类型的方法是重载和模板,都是在编译前进行处理。弱类型的就没有这个问题,入口参数想怎么传就怎么传,返回值想怎么给就怎给。

python 是弱类型语言,下面使用 python 定义了一个 add 函数,用于返回两个值相加的结果。在调用该函数时,可以使用各种类型。

  1. def add(a, b):

  2. return a b;

  3. print add(3, 5); #8

  4. print add(3.1, 5.1); #8.2

  5. print add("abc", "abd"); #abcabd

C 语言可以通过函数重载或模板来实现类似的方案。

1 函数重载

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

When two or more different declarations are specified for a single name in the same scope, that name is said to overloaded. By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations. Only function declarations can be overloaded; object and type declarations cannot be。

在实际开发中,有时候我们需要实现几个功能类似的函数,只是有些细节不同。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char、bool 等,我们需要通过参数把变量的地址传入函数内部。在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似:

void add1(int a, int b) ; //两个int相加

  • #include <iostream>

  • using namespace std;

  • int add(int a, int b)

  • {

  • return a b;

  • }

  • float add(float x, float y)

  • {

  • return x y;

  • }

  • int main()

  • {

  • int a, b;

  • float x, y;

  • cout<<"enter two int:";

  • cin>>a>>b;

  • cout<<"sum="<<add(a,b)<<endl;

  • cout<<"enter two float:";

  • cin>>x>>y;

  • cout<<"sum="<<add(x,y)<<endl;

  • system("pause");

  • cin.get();

  • return 0;

  • }

  • vc程序的使用方法(VC函数重载与函数模板)(1)

    为什么需要函数重载?

    • 试想如果没有函数重载机制,add函数就需要取不同的名字,需要为实现同一个功能的函数取很多个名字,这样做很不友好!

    • 类的构造函数跟类名相同,也就是说:构造函数都同名。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!

    • 操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如 可用于连接字符串等!

    C 是如何做到函数重载的

    C 代码在编译时会根据参数列表对函数进行重命名,例如void add(int a, int b)会被重命名为_add_int_int,void add(float x, float y)会被重命名为_add_float_float。当发生函数调用时,编译器会根据传入的实参去逐个匹配,以选择对应的函数,如果匹配失败,编译器就会报错,这叫做重载决议(Overload Resolution)。(不同的编译器有不同的重命名方式,这里仅仅举例说明,实际情况可能并非如此。)从这个角度讲,函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。

    2 函数模板

    为什么要有函数模板呢?函数模板可以认为是函数重载的进化版,函数重载在使用的过程中,针对不同数据的处理都要写不同的函数体,而且代码复用率不高,代码量大,冗繁,所以不知是哪个程序猿又发明了这个模板。用过模板的都知道,那叫一个简单,修改一下文字就可以轻松的应对很多问题了。函数模板也是这样,你定义一个函数模板,后面处理不同数据都直接调用改下数据类型就可以用了,不仅提高效率,而且不用写那长长的代码。

    函数模板定义:

    template <typename/class 标识符>

    函数定义

    【示例】两数相加(应用函数模板):

    1. #include <iostream>

    2. using namespace std;

    3. template<typename T>

    4. T add(T a,T b)

    5. {

    6. return a b;

    7. }

    8. int main()

    9. {

    10. int a, b;

    11. float x, y;

    12. cout<<"enter two int:";

    13. cin>>a>>b;

    14. cout<<"sum="<<add(a,b)<<endl;

    15. cout<<"enter two float:";

    16. cin>>x>>y;

    17. cout<<"sum="<<add(x,y)<<endl;

    18. system("pause");

    19. cin.get();

    20. return 0;

    21. }

    运行效果与函数重载的代码的效果一样。

    (利用函数模板就不用写那么长的代码啦,而且还能重复利用,省心)

    3 运算符重载

    C 中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C 中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。运算符重载的实质是函数重载,它提供了C 的可扩展性,也是C 最吸引人的特性之一。

    运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。运算符函数定义的一般格式如下:

    <返回类型说明符> operator <运算符符号>(<参数表>)

    {

    <函数体>

    }

    1. #include <iostream>

    2. using namespace std;

    3. class Box

    4. {

    5. public:

    6. double getVolume(void)

    7. {

    8. return length * breadth * height;

    9. }

    10. void setLength( double len )

    11. {

    12. length = len;

    13. }

    14. void setBreadth( double bre )

    15. {

    16. breadth = bre;

    17. }

    18. void setHeight( double hei )

    19. {

    20. height = hei;

    21. }

    22. // 重载 运算符,用于把两个 Box 对象相加

    23. Box operator (const Box& b)

    24. {

    25. Box box;

    26. box.length = this->length b.length;

    27. box.breadth = this->breadth b.breadth;

    28. box.height = this->height b.height;

    29. return box;

    30. }

    31. private:

    32. double length; // 长度

    33. double breadth; // 宽度

    34. double height; // 高度

    35. };

    36. // 程序的主函数

    37. int main( )

    38. {

    39. Box Box1; // 声明 Box1,类型为 Box

    40. Box Box2; // 声明 Box2,类型为 Box

    41. Box Box3; // 声明 Box3,类型为 Box

    42. double volume = 0.0; // 把体积存储在该变量中

    43. // Box1 详述

    44. Box1.setLength(6.0);

    45. Box1.setBreadth(7.0);

    46. Box1.setHeight(5.0);

    47. // Box2 详述

    48. Box2.setLength(12.0);

    49. Box2.setBreadth(13.0);

    50. Box2.setHeight(10.0);

    51. // Box1 的体积

    52. volume = Box1.getVolume();

    53. cout << "Volume of Box1 : " << volume <<endl;

    54. // Box2 的体积

    55. volume = Box2.getVolume();

    56. cout << "Volume of Box2 : " << volume <<endl;

    57. // 把两个对象相加,得到 Box3

    58. Box3 = Box1 Box2;

    59. // Box3 的体积

    60. volume = Box3.getVolume();

    61. cout << "Volume of Box3 : " << volume <<endl;

    62. cin.get();

    63. return 0;

    64. }

    如果没有运算符重载,上述Box3 = Box1 Box2;是不能使用“ ”运算的。

    reference

    http://blog.csdn.net/zhanghow/article/details/53588458

    http://blog.csdn.net/u011282704/article/details/39508801

    ,

    免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

      分享
      投诉
      首页