C++进阶2:重载

函数重载:

在相同作用域中的多个函数,具有相同的名字而形参表不同
不能仅仅基于不同的返回类型而实现函数重载。返回值是不影响函数签名的。

C++函数重载底层实现原理是C++利用name mangling(倾轧)技术,来改名函数名,区分参数不同的同名函数。

编译器通过函数名和其参数类型识别重载函数。为了保证类型安全的连接(type-safe linkage),编译器用参数个数和参数类型对每一个函数标识符进行专门编码,这个过程有时称为“名字改编”(name mangling)或“名字修饰”(name decoration)。类型安全的连接使得程序能够调用合适的重载函数并保证了参数传递的一致性。编译器能够检测到并报告连接错误。

1、查看符号表

(1)nm目标文件
(2)objdump -t 目标文件
(3)readelf -s 目标文件
(4)strings 目标文件

1.1 gcc编译

(1)tesst.c

int func(int a){};

(2)编译

gcc -c test.c -o test.o

(3)查看符号

objdump -t test.o

1.2 g++编译

(1)test.cpp

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

(2)编译

g++ -c test.cpp -o test.o

(3)查看符号

objdump -t test.o

_Z是规定前缀,4是函数名的字符个数,i是参数列表类型i的首字母
注意:不同系统和编译器的命名倾轧方式是有所不同的。

2、命名反倾扎

2.1 名字改编转化成函数名

使用c++filt命令可以很容易把名字改编转换成函数名。

c++filt _Z4funci

2.2 查看反倾轧的符号表

nm -C 目标文件

3、禁用命名倾轧

C++命名倾轧的函数是无法被C语言调用的。C++的函数必须是没有倾轧的才能调用。
使用声明extern "C"的函数会禁止命名倾轧,这样C++的函数就可以被C语言调用。
例如:

(1)sum.h

#ifndef __CPP_H_
#define __CPP_H_

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

int sum(int* arr,int n);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // __CPP_H_

通常为了头文件可以同时被C++/C使用,通常把extern "C"放在__cplusplus条件宏定义中。

(2)sum.cpp

#include "cppFunc.h"
#include <numeric>
using namespace std;

int sum(int* arr,int n){
    return accumulate(arr,arr+n,0);
}

(3)sum_test.c

#include <stdio.h>
#include "cppFunc.h"
int main(){
    int arr[] = {1,2,3,4,5};
    printf("%d\n",sum(arr,5));
}

4、原理小结

在这里插入图片描述
在这里插入图片描述

4、综合练习

(1)Test.h

#pragma once
//C++的时候,显示extern "C"
//C的时候,不显示extern "C"
#ifdef __cplusplus
extern "C"{//在函数声明中使用
#endif
int Add(int a,int b);
void FuncTest();
#ifdef __cplusplus
}
#endif

(2)Test.cpp

#include "Test.h"
int Add(int a,int b){
    return a+b;
}


void FuncTest(){}

(3)overload.cpp

#include "Test.h"

int Add(float a,long b){
    return a+b;
}

class Simple{
public:
    Simple(){}
    Simple(const Simple&){}
    Simple& operator=(const Simple&){return *this;}
    ~Simple(){}
};

void Func(){}

int main(){
    int c = Add(10,11);
//    Simple s;
//    Simple s2(s);
//    s2=s;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值