c++程序设计中的函数重载

函数重载的意思是在一个作用域内(命名空间内)定义了某个或某些具有相同名称的函数,但是他们的参数列表和定义(实现)不相同,如果相同的话,就没啥意义了。当调用一个重载函数时,编译器会通过所使用的参数类型、个数等与定义中的参数类型进行比较,决定选用最合适的定义,这个选择重载函数的过程就是重载决策。

比如我们可以在定义的类中、在某一个命名空间内使用函数重载:

#include <iostream>
#include<stdlib.h>
using namespace std;
//类内的函数重载
class Line
{
   public:
      void setLength( double len );
      void setLength(int len);
      double getLength( void );
      Line(); 
 
   private:
      double length;
};
 
// 成员函数定义,包括构造函数
Line::Line(void)
{
    cout << "Object is being created" << endl;
}
 
void Line::setLength( double len )
{
    length = len;
}
void Line::setLength( int len )
{
    length = len+1;
}
double Line::getLength( void ) 
{ 
return length; 
} 
//在std命名空间的函数重载,求两个数的和
int add(int x, int y) { return x+y; } int add(double x, double y) { return x+y; } int main( ) { Line line; line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; line.setLength(4); cout << "Length of line : " << line.getLength() <<endl; double a=add(3.0,4.0); int b=add(2,1); cout<<"a="<<a<<" "<<"b="<<b<<endl; system("pause"); return 0; }

执行上述代码,可以清晰地看到函数重载的现象,其实函数重载本身比较容易理解,但是其经常和函数模板一起使用,这是我遇到过的最普遍的情况,在介绍之前,我们先来了解一下命名空间namespace的用法,从学习c++开始,都知道std,但其实namespace也有很多,例如using namespace cv; using namespace caffe等等,因此我们要说明一下,而刚好函数重载就是在某一个作用域内发生的行为,即不同的命名空间即使函数名,形参都一样也没问题,不属于函数重载。

namespace 的基本格式如下:

namespace identifier

{

entities;

}

此处举个例子:

namespace adding

{

int a,b,c;

c=a+b;

}

为了在namespace外使用某个namespace内的变量或者成员函数时,当然要使用::操作符,如:

adding::a;

函数模板

在上面的例子中,我们为了求两个数的和,因为类型不一样,因此我们针对两个类型写了两个可谓一模一样的函数,重复工作量大,当然我们也不可能预先穷尽所有的可能,不利于项目的维护和发展。c++模板应运而生,模板是泛型编程的基础,即以一种独立于任何特定类型的方式编写代码。

函数模板(function template)是一个独立于类型的函数,这些函数与类型无关,并且只在实例化时才知道其类型,从而形成“批量型”的编程方式。显然应用函数模板可以解决上述问题。

函数模板的定义:

template<模板形参列表>函数的返回值类型 函数名(形式参数列表)       

{  

  函数体  

}  

模板定义以关键字template开始,后接模板形参列表;模板形参列表-是一对尖括号<>括起来的一个或多个模板形参表且不允许为空。  

形参之间以逗号隔开,有两种形式:  

  1. typename 参数1,typename 参数2....  
  2. class 参数1,class 参数2.....  

模板定义的后面就是函数定义,在函数定义中,可以使用模板形参表中的类型参数,例如:  

template<typename T> int add(T a,T A b)  

           {  

return a+b;  

           }  

两个语句分开较为正式:

template<typename T> 

int add(T a,T A b)  

           {  

return a+b;  

           }  

 

#include<iostream>  
#include<stdlib.h>
using namespace std;  
template<typename T>
int add(T a,T b) { return a+b; } int main() { cout<<"int "<<add(5,3)<<endl; cout<<"char "<<add('a','A')<<endl; system("pause"); return 0; }

 类模板

 类模板的定义

 template<模板参数列表>class 类模板名{  

            1--构造函数  

            2--析构函数  

            3--成员函数  

            4--数据成员  

        };  

类模板必须以关键字template开头,后接模板形参列表,模板参数用一对<>括住且不允许为空,形参之间以逗号分隔。如果说类是对象的抽象,对象是类的实例,则类模板是类的抽象,类是模板的实例。可以利用类模板建立支持各种数据类型的类。

        template<class T> 
        class Point{  
            public:  
                 //默认构造函数  
                 Point():x(0),y(0){}  
                 //带参数的构造函数  
                 Point(const T a,const T b):x(a),y(b){}  
                 //成员函数  void display(){  
                     cout<<"x:"<<x<<"    "<<"y:"<<y<<endl;  
                 }  
            private:  
                T x,y;  
        };  

定义完了模板可以在其基础上实例化对象,如上述模板可以初始化为:

Point <int>a,b;//实例化为整形的a和b类,应该执行默认的构造函数
a.display();
b.display();
Point<double>m(3.0,5.0),n(1.0,2.0);//实例化为double类型的m和n类,根据形参个数和类型应该执行带参数的构造函数
m.display();
n.display();

 

我们都在通往真理的路上。
原文地址:https://www.cnblogs.com/cvtoEyes/p/8492743.html