【C++】 9_函數重載分析 (下)

重載與指針

  • 函數重載趕上函數指針編程

    • 將重載函數名賦值給函數指針時函數

      • 根據重載規則挑選與函數指針參數列表一致的候選者
      • 嚴格匹配候選者的函數類型與函數指針的函數類型

編程實驗: 函數重載 VS 函數指針

#include <stdio.h>
#include <string.h>

int func(int x)
{
    return x;
}

int func(int a, int b)
{
    return a + b;
}

int func(const char* s)
{
    return strlen(s);
}

typedef int(*PFUNC)(int c);

int main(int argc, char* argv[])
{
    int c = 0;
    
    PFUNC p = func;
    
    c = p(1);
    
    printf("c = %d\n", c);

    return 0;
}
輸出:
c = 1
  • 注意指針

    • 函數重載必然發生在同一個做用域
    • 編譯器須要用參數列表函數類型進行函數選擇
    • 沒法直接經過函數名獲得重載函數的入口

應該怎樣得到某一個重載函數的地址呢?code

#include <stdio.h>

int add(int a, int b)  // int(int, int)
{
    return a + b;
}

int add(int a, int b, int c) // int(int, int, int)
{
    return a + b + c;
}

int main()
{
    printf("%p\n", (int(*)(int, int))add);        // 經過類型轉換獲得函數指針 
    printf("%p\n", (int(*)(int, int, int))add);

    return 0;
}

C++ 和 C 相互調用

  • 實際工程中 C++ 和 C 代碼相互調用是不可避免的(尤爲在已經存在的C源碼或C庫)
  • C++ 編譯器可以兼容 C 語言的編譯方式
  • C++ 編譯器會優先使用 C++ 編譯的方式
  • extern 關鍵字能強制讓 C++ 編譯器進行 C 方式的編譯
extern "C"
{
    // do C-style compilation here
}

編程實驗: C++ 調用 C 函數

add.h作用域

int add(int a, int b);

add.c編譯器

#include "add.h"

int add(int a, int b)
{
    return a + b;
}

main_1.cpp源碼

#include <stdio.h>
#include "add.h"

int main()
{
    int c = add(1, 2);
    
    printf("c = %d\n", c);
    
    return 0;
}
gcc -c add.c -o add.oo
g++ add.h add.oo main.cpp 
 
輸出:
main_1.cpp:(.text+0x19): undefined reference to `add(int, int)'
collect2: ld returned 1 exit status

main_2.cstring

#include <stdio.h>
extern "C"
{

#include "add.h"

}

int main()
{
    int c = add(1, 2);
    
    printf("c = %d\n", c);
    
    return 0;
}
輸出:
c = 3

分析:【不一樣的編譯方式致使不一樣的編譯結果】
gcc 編譯 add.c add.h 生成 add.oo 中的符號表
00000000 T add

g++ 編譯 add.c add.h 生成 add.oo 中的符號表
00000000 T _Z3addii
     U __gxx_personality_v0

問題: 如何保證一段 C 代碼只會以 C 的方式被編譯?

  • __cplusplus 是 C++ 編譯器內置的標準宏定義
  • __cplusplus 的意義:確保 C 代碼以統一的 C 方式被編譯成目標文件
#ifdef __cpusplus
extern "C" {
#endif

// C-Style Compilation

#ifdef __cpluscplus
}
#endif

編程實驗: C 調用 C++ 函數

add.hit

int add(int a, int b);

add.cio

#include "add.h"

int add(int a, int b)
{
    return a + b;
}

main.c

#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

#include "add.h"

#ifdef __cplusplus
}
#endif

int main()
{
    int c = add(1, 2);
    
    printf("c = %d\n", c);
    
    return 0;
}
輸出:
c = 3

注意事項:

  • C++ 編譯器不能以 C 的方式編譯重載函數
  • 編譯方式決定函數名被編譯後的目標名
  • C++ 編譯方式將函數名和參數列表編譯成目標名
  • C 編譯方式只將函數名做爲目標名進行編譯

小結

  • 函數重載是 C++ 對 C 的一個重要升級
  • 函數重載經過函數參數列表區分不一樣的同名函數
  • extern 關鍵字可以實現 C 和 C++ 的相互調用
  • 編譯方式決定符號表中的函數名的最終目標名

以上內容參考狄泰軟件學院系列課程,請你們保護原創!

相關文章
相關標籤/搜索