之前在看到C++函数重载那就想到想把这三个对比一下了,今天想起来,写篇推文记一下
。
1.
MATLAB中的plot函数可以接收一个参数,也可以接收两个,也可也接收三个及以上,但是他们都是用同一个函数名字plot,这是如何做到的?
plot(y)
plot(x, y)
plot(x, y, 'r-')
只有一个函数名,却可以有这么多种调用形式
2.
在C++中,也能像在MATLAB中那样让你使用多个同名的函数,这些同名函数的参数列表(特征标)不同。
这在C++中叫做函数重载;在MATLAB中不知道叫啥
,反正是通过nargin来实现的。
C++中函数重载的关键是函数的参数列表(也称为函数的“特征标”)。
3.
在Python中不支持函数重载,不过在python3中提供了一个装饰器叫:functools.singledispatch,用它可以来完成Python中的函数重载(具体没用过
,现在也没怎么看Python,忘了好多)。
实际上,Python 中函数的形参十分灵活,以至于它根本不需要重载,不过我们可以用收集参数:*args来模拟一下函数重载。
先介绍下nargin吧
n代表:number
arg代表:argument
in代表 : input
放一块就是输入参数的个数,它会自动识别用户向函数中传入了几个参数,用户输入了几个参数,那么nargin就是几。
至于函数重载呢
你在声明函数原型时多写几个同名的函数,但是一定要让他们的参数列表不同,可以是相同的参数个数但是参数类型不同,也可以是参数个数不同,等等;他们的返回类型可以相同也可以不同。
然后下面挨个去写他们的函数定义。
至于收集参数呢
在形参前面加上一个星号:*,那么这个参数就是收集参数了,收集参数实际上是一个tuple(元组,和MATLAB中的cell有点类似),它把用户往函数中传递的参数按顺序放到这个收集参数(元组)里,收集参数中的第一个元素是用户输入的第一个参数,以此往后类推。
比如:
def CalDistance(*cords):
pass
上面的cords就是一个收集参数,我上面所说的只对应函数只接受一个收集参数时的情况啊。
举个例子看一下:
图中的代码:
def CalDistance(*cords):
for i, item in enumerate(cords):
print('第', i, '个参数:', item)
if __name__ == '__main__':
CalDistance(1, 2, 3, 4, 5, 6)
拿一个常见的例子来说:计算两点之间的距离,这两点可以是空间的也可以是平面的。
如果是空间的话,那么计算两点距离一共要向函数中传递6个值;但是要是平面的话,那么计算两点距离则只要向函数传递4个值。
当然,你可以定义一个描述坐标的结构体,平面的话把z值设置为0就行,这样不管是算平面距离还是空间距离都只要向函数传递两个结构体就行。
一. 在MATLAB中nargin是这样做的:
function d = CalDistance(x1, x2, y1, y2, z1, z2)
if nargin == 4
d = sqrt((x1 - x2)^2 + (y1 - y2)^2);
elseif nargin == 6
d = sqrt((x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2);
else
disp('请输入正确的参数个数!')
d = [];
end
nargin是用户调用函数时向函数中传递的参数个数,如果发现nargin等于4,那么就用平面上计算两点间的距离公式;如果发现nargin等于6,那么就用空间中计算两点间的距离公式;如果输入的参数个数既不是4个也不是6个,那么就提示输入错误。
调用结果:
二. 在C++中用函数重载这样做
1. funcs.h
#ifndef FUNCS_H
#define FUNCS_H
//overload
double CalDistance(double x1, double x2, double y1, double y2);
double CalDistance(double x1, double x2, double y1, double y2, double z1, double z2);
#endif // FUNCS_H
在funcs.h头文件中声明了两个同名的函数的函数原型,它们的参数列表不同。
2. funcs.cpp
#include "funcs.h"
#include
double CalDistance(double x1, double x2, double y1, double y2){
double d;
d = sqrt( pow(x1-x2, 2) + pow(y1-y2, 2) );
return d;
}
double CalDistance(double x1, double x2, double y1, double y2, double z1, double z2){
double d;
d = sqrt( pow(x1-x2, 2) + pow(y1-y2, 2) + pow(z1-z2, 2) );
return d;
}
在funcs.cpp源文件中对这两个同名的函数进行了定义。
3. main.cpp
#include
#include "funcs.h"
int main(){
double d1 = CalDistance(1, 2, 1, 2);
double d2 = CalDistance(1, 2, 1, 2, 1, 2);
std::cout <
std::cout <
return 0;
}
在main.cpp中调用这两个同名的函数,调用的结果如下:
三. 在Python中用收集参数可以这样做
from math import sqrt
def CalDistance(*cords):
if len(cords) == 4:
x1 = cords[0]
x2 = cords[1]
y1 = cords[2]
y2 = cords[3]
d = sqrt((x1 - x2)**2 + (y1 - y2)**2)
elif len(cords) == 6:
x1 = cords[0]
x2 = cords[1]
y1 = cords[2]
y2 = cords[3]
z1 = cords[4]
z2 = cords[5]
d = sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)
else:
d = []
print('请输入正确的参数个数')
return d
if __name__ == '__main__':
d1 = CalDistance(1, 2, 1, 2)
print('CalDistance with 4 parameters: d1 = ', d1)
d2 = CalDistance(1, 2, 1, 2, 1, 2)
print('CalDistance with 4 parameters: d2 = ', d2)
运行结果如下:
还是MATLAB好用
。C++真的要写一堆,Python还好。
当时在看C++函数重载时就想到了另外这两种语言中的这个用法,当时就想着写一篇总结,一直拖着没做
,今天给放出来了。
--END--