C++深度解析 函數重載分析--函數指針,函數重載,C++和C互相調用(8)
函數指針
typedef 傳回類型(*新類型)(參數表)
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
typedef的功能是定義新的類型。第一句就是定義了一種PTRFUN的類型,并定義這種類型為指向某種函數的指針,這種函數以一個int為參數并傳回char類型。後面就可以像使用int,char一樣使用PTRFUN了。 第二行的代碼便使用這個新類型定義了變量pFun。
函數重載 VS 函數指針
函數重載遇上函數指針時:
将重載函數名指派給函數指針時
1、根據重載規則挑選與函數指針參數清單一緻的候選者
2、嚴格比對候選者的函數類型與函數指針的函數類型
示例程式:(函數重載 VS 函數指針)
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(char* s)
{
return strlen(s);
}
//函數指針類型PFUNC
typedef int(*PFUNC)(int a);
int main(int argc, char* argv[])
{
int c = 0;
//函數指針p
PFUNC p = func;
//根據函數指針p,所指向參數清單進行選擇:(int a)
//嚴格比對函數類型:int
c = p(1);
printf("c = %d\n", c);
return 0;
}
結果如下:
從上述例子,注意:
函數重載必然發生在同一個作用域中。
編譯器需要用參數清單或函數類型進行函數選擇。
無法直接通過函數名得到重載函數的入口位址(參考上一章節的最後一個例子!!!!)
C++和C互相調用
C++編譯器要相容C語言的編譯方式。
C++編譯器會優先使用C++編譯的方式
extern關鍵字能強制讓C++編譯器進行C方式的編譯
//告訴C++編譯器,下面的代碼是以C語言的方式編譯
extern "C"
{
//do C-style compilation here
}
示例程式:(建立立一個檔案夾)
add.h
int add(int a, int b);
add.c
#include "add.h"
int add(int a, int b)
{
return a + b;
}
main.cpp(調用C函數)
#include <stdio.h>
//告訴C++編譯器,add.h包含的内容(C代碼)必須用C方式編譯
extern "C"
{
#include "add.h"
}
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
結果如下:(*.o 目标檔案)
通過nm指令,檢視add.o目标檔案(用C語言編譯器編譯的)的符号表資訊,檢視是否有add函數。
保證代碼,即被C的編譯器編譯過,也被C++的編譯器編譯過。
__cplusplus是C++編譯器内置的标準宏定義,可以測試目前的編譯器 是不是 C++編譯器
__cpluscplus:確定C代碼以統一的C方式被編譯成目标檔案
示例程式:
#include <stdio.h>
//兩個#ifdef #endif
#ifdef __cplusplus //如果是C++編譯器(__cplusplus測試目前的編譯器 是不是 C++編譯器)
extern "C" {
#endif
#incldue "add.h"
#ifdef __cplusplus
}
#endif
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
結果如下:
C++編譯方式将函數名和參數清單編譯成目标名
示例程式:
int add(int a, int b)
{
return a + b;
}
int add(int a, int b, int c)
{
return a + b + c;
}
結果如下:
分析:從上圖可以知道test.oo的符号表,_Z3addii和_Z3addiii這兩個是被編譯後的目标函數名(附加資訊),ii和iii代表參數的個數,ii表明有兩個參數int,iii表明有三個參數int。
注意事項
C++編譯器不能以C的方式編譯重載函數。
編譯方式決定函數名被編譯後的目标名。
C++編譯方式将函數名和參數清單編譯成目标名
小結:
函數重載通過函數名和參數清單,來區分不同的同名函數。
在extern "C"代碼塊中,不能存在重載函數!!!
函數傳回值不能作為函數重載的依據。