C++作為C語言的擴展集,幾乎所有的C程序都可以在C++中編譯和運行,但是要注意C程序中可能使用了C++中的關鍵字作為變量,比如在C中:int class = 0; 但這在C++中不行。出於方便性,我們可以在類中(C++)調用函數(C),也可以在函數(C)中使用對象(C++)。
混合C和C++時,可能會丟失面向對象的特性,比如在C++編寫的程序中使用了C的函數庫,此時可以對C的函數進行重新封裝為一個易用的類,一般可以將C函數的返回值作為類的一個成員。
C++通過name mangling支持函數重載,但是C語言不支持,其將重載看作重定義。默認情況下,C++編譯器會對每一個函數執行name mangling,即生成比較奇怪的函數名,但是如果此時需要鏈接一個C語言函數庫,那么C++編譯器由於找不到這些奇怪的名字,而宣告編譯失敗。因此,必須顯式告訴C++編譯器,此函數使用某種語言規范命名,通過使用extern ”language”說明,其語法為:
extern “language” void func1();
extern “language” void func2();
或者:
extern “language”{
void func1();
void func2();
}
如:
extern “C” void func(int i); /* 表明func(int i)是一個外部的C函數,告訴C++編譯器,該代碼是用C語言編寫的 */
使用extern的情況通常是在頭文件中,比如現在想使用一個C語言編寫的函數庫,這個函數庫可能有一個.h文件,此時我們可以編寫一個新的頭文件.hpp,將原來的頭文件放在extern模塊中,表示該頭文件中定義的函數都是用C語言編寫的:
// new_head.hpp
extern “C”
{
#include “old_head.h”
}
還有,我們可以通過條件編譯選擇到底使用C模塊還是C++模塊:C++編譯時會定義一個符號__cplusplus,而C編譯時該符號未定義,因此通常可以定義如下形式的頭文件:
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
void func1();
void func2();
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
上述代碼確保C和C++程序員都可以正確使用func1()和func2()。
