C++与C#对比学习:函数(三)函数名与变量名同名问题

函数重载与函数重名

 

函数重名

我们知道在相同的作用域中,不能定义两个名字相同的变量.那同样也不能定义两个"名字相同"的函数.不过我们判断两个函数是否同名不是仅仅根据函数名,而是根据函数签名.函数签名是由函数名和形参列表决定的.函数名字同不同我们瞧一眼就知道了.但形参列表同不同就比较复杂点了啊.

形表列表中参数的个数不相同自然就是不一样的了.所以我们重点来看看参数个数相同的情况

 

在C#中由于形参只能用ref和out两个修饰词,所以比较简单.

void Fun(int age) { }

void Fun(ref int age){ }        

这是两个不同的函数.

而void Fun(out int age){ }与void Fun(ref int age)是当作相同的函数签名了.

void Fun(int age){ } 与int Fun(int age) { return 1} 是相同的函数签名.因为返回值类型不属于函数签名考虑的范畴.

 

C++中情况复杂一点.

(1)void  Fun (int [5]) {  }  与void Fun(int [2]){ }

这是相同的函数签名,因为数组做参数时只是传数组的首地址.你这样指定数组的大小会被忽略掉.不管指定大小是多少都没用.

所以假如定义了函数void  Fun (int [5]){ }

int arr1[] = {1,2,3};

int arr2[] = {7,6,5,4,3};

Fun(arr1);

Fun(arr2);   //这两个调用都正确

而在C#中函数void Fun(int [5]) { }是不能通过编译的.不能去指定数组大小.

 

如果要传个数组进去并且指定数组大小的话.应该用数组的引用

void  Fun( int (&arr) [5]) { } 此时函数大小指定大小不一样就是不同的函数了.比如函数void Fun(int (&arr) [2]) { }就是函数签名不 同的函数.

所以假如定义了函数void  Fun (int [3]){ }

int arr1[] = {1,2,3};

int arr2[] = {7,6,5,4,3};

Fun(arr1);    //正确

Fun(arr2);   //错误

 

(2)void Fun(int* a){ } 与void Fun(int a[5]){ }是相同的函数签名

前面有讲了传数组做参数实际上相当于传它的首地址进去.而int[] 数组的首地址的类型就是int* 型的.

 

(3) void Fun(int* a){ } 与void Fun(const int* a) { }这是两个不同的函数签名

    void Fun(int& a){ } 与void Fun(const int& a){ }这也是两个不同的函数签名

它们前面加不加const就不一样的.但这只针对指针和引用,对其他任何类型就不适用了.

比如void Fun(int a){ }与void Fun(const int a){ }就是相同的函数签名了.

这看起来有点奇怪.为啥其他类型就不行了啊.据说是为了兼容C而这样设计,在C中参数加不加const都当成一样处理.那C中也有指针的啊,为啥指针加不加const就不一样了啊.没搞明白这是为啥呢?

 

明白了函数重名就容易理解啥叫函数重载了.就是定义几个函数名字相同,函数签名不同的函数.

比如定义了如下三个函数

void Fun(int age, string name){ }

void Fun(int* age){ }

void Fun(const int& age){ }

这就叫函数重载

 

函数名与变量名同名问题

上面我们说的是 定义不同的函数时只要函数签名不同就行.但函数名与一般变量名之间有冲突吗?肯定也有的

比如在一个class中

class Arwen

{

        public:

          int Fun;

          void Fun();       //出错了.函数名Fun与成员变量名字相同的了

}

不过如果一个是是全局作用域一个是局部作用域情况会有点区别,比如

class Arwen

{

        public:

          int Fun();

          void Test(){ int Fun;}    

 //此时在函数Test中定义一个变量Fun是不会报错的.但在Test函数体内,Fun这个局部变量屏蔽了函数名Fun,这与一般变量中局部变量屏蔽全局变量的规则是一样的.所以在函数Test如果调用函数Fun就会出错例如

//Test()

 {

int Fun;

Fun();    //出错了

  }

 

为啥函数名字相同但形参不同就不会报错,而变量名字和函数只要名字一同就报错了?

为啥不能让函数与变量同名我们也比较好理解.因为函数名有时也能当一般的变量类型一样用,比如有函数指针的话,我们可以把函数名作为右值赋给函数指针.如果要判断两个相同的名字是普通变量还是函数名会给编译器带来一些难度.所以编译器偷懒干脆就不让你们同名好了.实际上如果编译器要多做些事是可以做到让函数名与一般变量名相同的.据说有些语言或有些编译器中确实可以做到让函数名与变量名相同.只是能够让函数与变量同名又没啥实际好处,所以费力不讨好的事还是少做了.另外编译器让函数名可以相同,只要函数签名不同即可自然是为了支持函数重载这样的特性.这是吃力但讨好的事.其实编译语言中很多错误不是说真的不能那样,只是编译器会遵守一定的规则去检查.如果换个编译器可能遵守的规则又不一样了.这时错的也变成对的了.

 

在C#中函数与变量同名的问题跟C++中是一样的处理

 

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值