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编译时该符号未定义,因此通常可以定义如下形式的头文件:
#ifndef __cplusplus
extern "C"
{
#endif // __cplusplus
void func1();
void func2();
#ifndef __cpluscplus
} // extern "C"
#endif // __cpluscplus
上述代码确保C和C++程序员都可以正确使用func1()和func2()。