您的位置:首页 > 其它

函数重载

2016-06-16 02:23 162 查看
一 概念

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

函数重载(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 function
cout << 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 called
cout << "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.0
void 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+10
using 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转换为UPInts
upi3 = 10 + upi2;
getchar();
return 0;
}
/*
1 内联它与一般函数所不同之处只在于函数调用的处理。。编译的时候展开
2 一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换
3 另外内联的函数无法进行断点调试
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: