C++为什么支持函数重载,C语言不支持函数重载?
C++代码产生函数符号时, 是函数名+参数列表类型组成的!如_Z3sumii
C代码产生函数符号时,只由函数名决定
什么是函数重载?
一组函数,其中函数名相同,参数列表个数或类型不同,那么这组函数称为函数重载
仅返回值不同不构成重载。
解释什么是多态
静态多态(编译时):函数重载、模板
动态多态(运行时)
先处于同一作用域,才可以谈重载,如下例子
bool compare(int a, int b) // compare_int_int
{
cout << "compare_int_int" << endl;
return a > b;
}
bool compare(double a, double b) // compare_double_double
{
cout << "compare_double_double" << endl;
return a > b;
}
bool compare(const char *a, const char *b) // compare_const char*_const char*
{
cout << "compare_char*_char*" << endl;
return strcmp(a, b) > 0;
}
int main()
{
bool compare(int a, int b); // 函数的声明,导致编译器不会去外面找别的compare定义,
compare(10, 20); // call compare_int_int
compare(10.0, 20.0); // double -> int
compare("aaa", "bbb"); // const char* => int,error!!!
return 0;
}
上述代码compare("aaa", "bbb");
出错
const
和volatile
的情况会影响形参类型(后面细讲),如:
void func(int *a) {} // int
void func(int *const a) {} // 错误,重定义
int main()
{
int a = 10;
const int b = 10;
cout << typeid(a).name() << endl; // int
cout << typeid(b).name() << endl; // int
return 0;
}
而如下却是通过编译
void func(int *a) {} // int
void func(int const *a) {}
函数参数 const int 和int的话编译器分不出区别,造成重定义
C++和C语言代码间如何相互调用
在linux上测试时,c文件链接用gcc
,c++文件用g++
,不然没效果
C++调用C函数
由于符号生成规则的问题,用extern "C "
因为C++中函数声明生成符号带参数类型,而C文件中函数生成符号不带参数类型,两者不匹配,故在函数声明处加extern "C ":
// main.cpp
extern "C"{
int sum(int a, int b);
}
int main()
{
int ret = sum(10, 20);
cout << "ret = " << ret << endl;
return 0;
}
// test.c
int sum(int a, int b)
{
return a + b;
}
对main.cpp 编译得到目标文件并查看目标文件符号表
jyhlinux@ubuntu:~/share/cppmid/inline$ g++ -c main.cpp test.c
jyhlinux@ubuntu:~/share/cppmid/inline$ objdump -t main.o
可看出此时以C方式生成符号。再对test.c
编译得到目标文件并查看目标文件符号表
jyhlinux@ubuntu:~/share/cppmid/inline$ g++ -c main.cpp
jyhlinux@ubuntu:~/share/cppmid/inline$ gcc -c test.c
可以看出定义的符号和声明处的符号一致
最后这里我想通过 ld -lstdc++ main.o test.o -o main生成可执行文件但是失败了。提示ld: cannot find -lstdc++
C调用C++的函数代码
即函数定义写在cpp文件中
// main.cpp
extern "C"
{
int sum(int a, int b)
{
return a + b;
}
}
// test.c
#include <stdio.h>
int sum(int, int);
int main()
{
int ret = sum(10, 20);
printf("ret = %d\n", ret);
return 0;
}
编译执行成功:
gcc -o main main.cpp test.c
如果不把定义放在extern "C"中则提示:
注意:这个extern "C"
是写在cpp
文件中的!!!!
补:说明一下如下代码意思
#ifdef __cplusplus
extern "C" {
#endif
int sum(int a, int b) // sum .text
{
return a + b;
}
#ifdef __cplusplus
}
#endif
C++编译器都内置了__cplusplus
宏名,保证了若是以C++编译该该代码,可以保证以C方式生成符号使得不管是在C还是C++文件中定义该函数,都能够在C文件中使用该函数。
参考资料
施磊.C++基础进阶课