1. 程式人生 > >第9課-函式過載分析(下)

第9課-函式過載分析(下)

一、過載與指標

下面的函式指標將儲存哪個函式的地址?

這裡寫圖片描述

  • 函式過載遇上函式指標
    • 過載函式名賦值給函式指標
      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(const char* s) { return strlen(s); } typedef int(*PFUNC)(int a); int main(int argc, char *argv[]) { int c = 0; PFUNC p = func; c = p(1); printf("c = %d\n", c); return 0; }

列印結果:

c = 1   

注意:

  • 函式過載必然發生在同一個作用域中
  • 編譯器需要用引數列表函式型別進行函式選擇
  • 無法
    直接通過函式名得到過載函式的入口地址

二、C++和C相互呼叫

  • 實際工程中C++和C程式碼相互呼叫是不可避免的

  • C++編譯器能夠相容C語言的編譯方式

  • C++編譯器會優先使用C++編譯的方式

  • extern關鍵字能強制讓C++編譯器進行C方式的編譯

    extern "C"{
    // do C-style compilation here
    }

程式設計實驗:C++呼叫C函式

如何保證一段C程式碼只會以C的方式被編譯?

檔案一:add.c

#include "add.h"

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

檔案二:add.h

int add(int a, int b);

檔案三:main.cpp

#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;
}

解決方案:

  • __cplusplus是C++編譯器內建的標準巨集定義

  • __cplusplus的意義

    • 確保C程式碼以統一的C方式被編譯成目標檔案
    
    #ifdef __cplusplus
    
    extern "C" {
      #endif
      //C-Style Compilation
      #ifdef __cplusplus
    }
    
    #endif
    

注意事項:

  • C++編譯器不能以C的方式編譯過載函式
  • 編譯方式決定函式名被編譯後的目標名
    • C++編譯方式將函式名引數列表編譯成目標名
    • C編譯方式只將函式名作為目標名進行編譯

三、總結

  • 函式過載是C++對C的一個重要升級
  • 函式過載通過函式引數列表區分不同的同名函式
  • extern關鍵字能夠實現C和C++的相互呼叫
  • 編譯方式決定符號表中的函式名的最終目標名