专业编程基础技术教程

网站首页 > 基础教程 正文

VC++|函数重载与函数模板(c++函数重载是什么)

ccvgpt 2024-08-03 12:32:07 基础教程 14 ℃

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

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

VC++|函数重载与函数模板(c++函数重载是什么)

  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相加

void add2(float a, float b); //两个float相加

但在C++中,这完全没有必要。C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载(Function Overloading)。借助重载,一个函数名可以有多种用途。(参数列表又叫参数签名,包括参数的类型、参数的个数和参数的顺序,只要有一个不同就叫做参数列表不同。)

【示例】两数相加(应用函数重载):

  1. #include <iostream>

  2. using namespace std;

  3. int add(int a, int b)

  4. {

  5. return a+b;

  6. }

  7. float add(float x, float y)

  8. {

  9. return x+y;

  10. }

  11. int main()

  12. {

  13. int a, b;

  14. float x, y;

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

  16. cin>>a>>b;

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

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

  19. cin>>x>>y;

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

  21. system("pause");

  22. cin.get();

  23. return 0;

  24. }

为什么需要函数重载?

  • 试想如果没有函数重载机制,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

Tags:

最近发表
标签列表