• 函数重载


    之前就有说过构造函数的重载了,并且对重载、重构、方法重写这三个易混淆的概念。这一次看到的是重载的一般概念,对于一般函数甚至操作符都有重载,而不只是构造函数。
    重载的使用场合有:
    1.相同(或相近)功能,相同参数,不同类型的函数不必单独命名。这一点应该说是编程语言本身的限制造成的,如果编程语言能够自动转换各种不同类型,我们根本不必为不同类型的函数独立编程。
    如:我们要一个交换两个变量的函数,

    using System;

    public class m
    {
     
    static void Main()
     
    {
      
    int x=12;
      
    int y=15;
      HY.swap(
    ref x, ref y);
      Console.WriteLine(
    "x=" + x + "; y=" + y);
     }

    }


    static class HY
    {
     
    public static void swap(ref int a, ref int b)
     
    int t=a;
       a
    =b;
       b
    =t;
     }

    }

    如果前面的x与y改为
      float x=12;
      float y=15;
    编译时,系统就会提示:
    p.cs(9,3): error CS1502: 与“HY.swap(ref int, ref
            int)”最匹配的重载方法具有一些无效参数
    p.cs(9,15): error CS1503: 参数“1”: 无法从“ref float”转换为“ref int”
    p.cs(9,22): error CS1503: 参数“2”: 无法从“ref float”转换为“ref int”
    目前,我们的做法要么增加一个新的函数名(如swap_float),要么我们用重载,只让函数名不增加,但函数还是要写的。
    以后,我试着找一下有没有可能函数只要写一个,就能在性能不明显降低的情况下适应各种情况。

    2.相同(或相近)功能,参数个数不同。《大话设计模式》中的例子,一只小狗不是一定要有姓名之后才能诞生的,可以先诞生,让它的名字为“无名”,然后在合适的时候给它取个名字。虽然这是对构造函数而言,但对一般的函数也是有类似的情况,这时也为了不增加函数名称,使用重载。
    但如果这样用重载导致代码重新再写过一遍,我感觉划不来,还不如宁可使用VB的optional方式。实际的编程一定是写一个完整参数的函数,然后缺胳膊少腿的重载函数在内部补全默认参数后,再调用完整参数的函数,但冥冥之中,总感觉更好的形式不应该是这样的。

    即使到现在,我还不能接受重载的意义,但重载的其它内容还是要继续测试下去的。

    注意事项中有提到四点:一是入口参数类型要不同,而不是入口参数要不同,如以下代码将会编译不通过:

    using System;

    public class m
    {
     
    static void Main()
     
    {
      point p
    =new point();
      p.showxy(
    1221);
     }

    }


    class point
    {
     
    public void showxy(int x, int y)
     
    { Console.WriteLine("x=" + x + "; y=" + y); }
     
    public void showxy(int y, int x)
     
    { Console.WriteLine("x=" + x + "; y=" + y); }
    }

    编译器提示:
    p.cs(16,14): error CS0111:
            类型“point”已定义了一个名为“showxy”的具有相同参数类型的成员
    p.cs(14,14): (与前一个错误相关的符号位置)
    第二个showxy本想让如果进入的参数是颠倒的,在代码中把它调正。但对于“p.showxy(12, 21);”,即使是人,都不知道到底是不是颠倒了xy。

    第二点,重载的函数返回值可以不相同。不知道是以前的C++不允许相同,还是书上写错了,反正我手头上一本书是说重载的函数之间返回值必须相同,但我输入如下代码后,在VS2005环境中,自动提示功能正常,并且编译也正常。

    using System;

    public class m
    {
     
    static void Main()
     
    {
      point p
    =new point();
      p.showxy(
    1221);
     }

    }


    class point
    {
     
    public void showxy(int x)
     
    { Console.WriteLine("x=" + x ); }
     
    public int showxy(int x, int y)
     
    { Console.WriteLine("x=" + x + "; y=" + y);
       
    return 0; }

    }
    第三点:“调用不确定问题”
    using System;

    public class m
    {
     
    static void Main()
     
    {
      point p
    =new point();
      p.showxy(
    3.8);
     }

    }


    class point
    {
     
    public void showxy(float x)
     
    { Console.WriteLine("x1=" + x ); }
     
    public void showxy(double x)
     
    { Console.WriteLine("x2=" + x ); }
    }

    执行结果会是什么?
    标准答案:x2=3.8

    系统是会自动按着默认的规则进行类型转换,基本原则是从低精度的可以转为高精度。如果是以下的代码,对于编程人员来说不一定是个好习惯,但对于编译器来说,怎么不提个醒?

    using System;

    public class m
    {
     
    static void Main()
     
    {
      point p
    =new point();
      
    int x=12;
      p.showxy(x);
     }

    }


    class point
    {
     
    public void showxy(float x)
     
    { Console.WriteLine("x1=" + x ); }
     
    public void showxy(double x)
     
    { Console.WriteLine("x2=" + x ); }
    }
    第四点:重载用到父类与子类时,与方法重写有什么区别?
    以下代码执行正常:
    using System;

    public class m
    {
     
    static void Main()
     
    {
      point p
    =new point();
      p.showxy(
    12);
      rectpoint rp
    =new rectpoint();
      rp.showxy(
    1215);
     }

    }


    class point
    {
     
    public void showxy(int x)
     
    { Console.WriteLine("x=" + x ); }
    }

    class rectpoint:point
    {
     
    public void showxy(int x, int y)
     
    { Console.WriteLine("rect:x=" + x + ";y=" + y); }
    }
    对于showxy,这算是重载,还是重写?

  • 相关阅读:
    移植BOA
    [转]Ubuntu(Linux)使用Eclipse搭建C/C++编译环境
    服务器软件设计的算法和问题
    [solve]Bind: Address Already in Use
    Simple guide for Automake/Autoconf by Nick
    Ubuntu(Linux)中设置samba
    VMware不能上网,解决办法
    数组的顺序存储和实现
    根文件系统的构成
    Linux网络编程IP转换函数inet_addr和inet_ntoa
  • 原文地址:https://www.cnblogs.com/yzx99/p/1216437.html
Copyright © 2020-2023  润新知