函数重载

来源:互联网 发布:智慧医疗 物联网 知乎 编辑:程序博客网 时间:2024/06/06 09:46

一 概念

         同一作用域的一组参数列表不同,函数名相同的函数 这组函数叫

          函数重载(C++允许定义相同名称的函数)
  作用:
重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,
    避免了名字空间的污染,对于程序的可读性有很大的好处(一物多用)

  参数列表不同:

                1 参数类型不同

                2 参数顺序不同
                3 参数个数不同

   重载版本根据参数的匹配度进行选择

注意:

1.1 与函数参数的变量名无关
1.2 函数的返回值类型与重载无关
2 函数重载的实现原理是通过c++换名实现的
  extern “C” int fun() 的形式可以以c的方式生成函数名(无换名机制)
3 使用场景:
  当函数基本上执行相同的任务 使用不同形式的数据时 

二 哑元函数
哑元函数:参数只有类型没有形参名的函数 
        void fun(int); 
  功能:1 保持向前兼容性
        2 做函数的区分
          T operator++()   {}
          T operator++(int){}
 三 缺省参数
  如果函数的形参有缺省值,当函数调用时没有传递实参,那么形参就使用缺省
  值,如果调用函数时传递了实参,那么形参就使用实参的值
  注意:
   1 缺省参数靠右原则 如果一个函数有多个参数 且部分参数有缺省值那么缺
     省值的参数必须靠右(在编译期间确定参数)
   2 如果函数的声明和定义分开 那么缺省参数只能写在函数的声明部分
   3 注意防止重载的冲突(歧义)
   4 c++中函数的规则 不接受任何参数(否则可能构成重载)
    5  凼数参数的缺省值叧能在凼数声明指定 

四 内联 

 函数使用关键字inline 关键字修饰的函数叫做内联函数
  函数调用过程 :调用用后立即存储该指令的内存地址
                 将函数参数复制到堆栈
                 跳到标记函数起点的内存单元 执行函数代码(可能还有返回
                 值放入到寄存器中)
    将返回值弹出
                 然后跳回到地址被保存的指令处 
 内联的实质:
  就是把函数编译好的二进制代码 替换成函数的调用指令(省去了调用开销)


(空间换取时间)
注意:
  1类中直接定义的函数自动被处理成内联函数,所以一般把内联函数放在头文
   件中
  2 inline是一种请求,实现方式取决于编译器,特别是当函数较大或是递归
    的时候


#include<iostream>using namespace std;namespace overload{void add(int a, int b){cout << "int:"<<a + b << endl;}void add(double a,double d){//变量名可以不同cout << "double:" << a + d << endl;}void add(int a, double d){cout << "int double:" << a*d << endl;}}namespace show{void print(char c){cout << "show1 =" << c << endl;}void print(char c, char d){cout << "show2 =" << c << d << endl;}}void fun(int a, int b){cout << "fun1:" << a + b << endl;}/*int fun(int a, int b){cout << "fun2:" << endl;return a*b;}是参数不同 与函数返回值类型无关*/int fun(int a, double b){cout << "fun2:" << a*b<<endl;return 0;}int main(){using namespace overload;add(1, 2);add(3.1, 4.1);add(1, 2.0);//add("abc", 2); 参数类型 无法进行匹配show::print('a');show::print('a', 'b');fun(5, 6);fun(5, 6.1);//add("abc", 2.1);无法匹配void(*paddII)(int, int) = add;//根据函数指针类型中的参数表信息确定其他所指向的重载版本void(*paddDD)(double, double) = add;void(*paddID)(int, double) = add;cout << "-------" << endl;paddII(3, 4);paddDD(3.3, 4.4);paddID(2, 3.3);//paddID('a');//system("pause");return 0;}



#pragma comment(lib,"CPP.lib")int main(){ cout << "max=" << max(1, 2) << endl;//cout << "max=" << max(1.1, 2.2) << endl;system("pause");return 0;}//vim add.c//add(int i,int j){//return i+j;//}//cp add.c add.cpp//gcc -c add.c_//nm add.o//000000000 (编译模块的相对地址) T (代码段test) add//g++ -c add.cpp//nm add.o//  T _Z3addii    ii(int int)//  T _Z3adddd      (double double)//  _Z 编译标记 每个编译器不一样    3  函数名长度//  //  我是一个C程序员 写一个程序 调用//  vim main.c//  #include<stdio.h>//  int add(int ,int);//  int main(){//  printf("%d\n",add(123,456));//  return 0;//  }//  gcc main.c add.oc//  gcc -c main.c//  nm main.o//  U add           U 外部 没换名//  // 


#include<iostream>using namespace std;void  fun(short s = 0, int i = 1, double d = 2.2);/*void fun(short s = 0, int i = 1, double d = 2.2){cout <<"fun(short,int,double):"<< s<<" "<<i<<" "   << d << endl;}*//*void fun(short s = 0, int i = 1 ){//ambiguous call to overloaded functioncout << s << " " << i << " "  << endl;}*/void bar(short s  , int i , double d = 2.2){//靠右原则  windows的很多函数 的带缺省值的都放在后面cout << "bar(short,int,double):" << s << " " << i << " " << d << endl;}void fun(void){cout << "fun(void)" << endl;}/*void foo(const int ){//数据类型一样,但属性不一样 和下面的不能进行重载the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or calledcout << "foo(const int )" << endl;}*/void foo( int ci){cout << "foo(int )" << endl;}void foo(const int* ci){ // 引用类型的可以cout << "foo(const int )" << endl;}void foo(int* ci){cout << "foo(int )" << endl;}//Inparticular, for any type T, “pointer to T, ” “pointer to const T, ” and “pointer to volatile T” areconsidered distinct parameter types, as are “reference to T, ” “reference to const T, ” and “reference tovolatile T.”int main(){int i = 0;const int*ci = &i;foo(&i);foo(ci);fun(1,2,3.0);fun(1, 2);fun(1);//fun();bar(1,2);//重载冲突 getchar();return 0;}void fun(short s /*=0*/, int i/*=1*/, double d /*=2.2*/){//函数定义时可以不写缺省参数cout << s << " " << i << " " << d << endl;}


#include<iostream>using namespace std;//version 1.0  向下兼容/*void compress(string s){cout << "compress.." << "finish" << endl;}*///version 2.0void compress(string){cout << "compress.." << "finish" << endl;}//-----区分重载版本void fun(int x, int y){cout << "fun1:"<<x<<' '<<y << endl;}void fun(int x, int y, int){cout << "fun2:" <<x<<' '<<y<< endl;}//上面两个函数换一下名就可以//-----但有的时候函数名只能用一个。。operator++int main(){compress("abc");compress("sdflj");fun(1, 2);fun(1, 2, 3);getchar();return 0;}

#include<iostream>#define ADD(a,b) (a+b)//宏不能访问对象的私有成员 宏的定义很容易产生二义性(MUL(X) (X*X)) MUL(10+10) === 10+10*10+10using namespace std;inline int add(int a,int b){//在类里定义的成员函数会被隐含指定为内置函数return a + b;}inline int foo(int i){/*if (i == 1 || i == 2){return 1;}*/return (i==1||i==2)?1:(foo(i-1) + foo(i - 2));}class UPInt{public:UPInt() { m_i = 0; }UPInt(int value) { m_i = value; }//..friend const UPInt operator+(const UPInt&lhs, const UPInt &rhs);private:int m_i;};const UPInt operator+(const UPInt&lhs, const UPInt &rhs){cout << "operator+" << endl;UPInt UPIntTemp(lhs.m_i + rhs.m_i);return UPIntTemp;}//const UPInt operator+(int lhs, int rhs); // 错误!这C++中有一条规则是每一个重载的operator必须带有一个用户定义类型(user-defined type)的参数int main(){cout << add(1, 2) << endl;cout << ADD(1, 2) << endl;for (int i = 1; i < 10;i++)cout << foo(i) << endl;UPInt upi1, upi2;UPInt upi3 = upi1 + upi2;upi3 = upi1 + 10;//这些语句也能够成功运行。方法是通过建立临时对象把整形数10转换为UPIntsupi3 = 10 + upi2;getchar();return 0;}/*1 内联它与一般函数所不同之处只在于函数调用的处理。。编译的时候展开2 一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换3 另外内联的函数无法进行断点调试*/




0 0
原创粉丝点击