您的位置:首页 > 编程语言 > C语言/C++

C++与C# 对函数隐藏的不同处理

2008-10-21 12:10 337 查看
看一段简单的C++代码

#include <iostream>

class A

{

public:

    void f(float x)

    {

        std::cout << "A::f(float)" << std::endl;

    }

    void f(int x, int y)

    {

        std::cout << "A::f(int,int)" << std::endl;

    }

};

class B : public A

{

public:

    void f(int x)

    {

        std::cout << "B::f(int)" << std::endl;

    }

};

int main(int argc, char * argv[])

{

    B b;

    b.f(2.3);

    // b.f(2,3); occur error

    return 1;

}

执行结果应该是什么呢?

记住这种情况不会实现函数重载的,因此调用b.f(2,3)会出现编译错误,而调用b.f(2.3)不会调用基类的f函数,而会调用派生类的f函数(参数类型隐性转换),函数隐藏的概念摘录如下

隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)

如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
再看同样代码的C#实现

using System;

using System.Collections.Generic;

using System.Text;

namespace FunctionTest

{

    class Program

    {

        static void Main(string[] args)

        {

            B b = new B();

            b.f(2.3f);

            b.f(2, 3); // work well

        }

    }

    public class A

    {

        public void f(int x)

        {

            Console.WriteLine("A::f(int)");

        }

        public void f(int x, int y)

        {

            Console.WriteLine("A::f(int,int)");

        }

    }

    public class B : A

    {

        public void f(float x)

        {

            Console.WriteLine("B::f(float)");

        }

    }

}

会发现与C++的不同之处,在C#中不会进行函数隐藏,即使派生类与基类同名,参数不同也能实现类似函数重载,执行结果是

A::f(float)

A::f(int,int)

这样的结果才会符合我们预期的设想,也许这也算是C++设计的一个不足之处吧

为了验证这真的算是函数重载么,把上面的程序简单改变一下,再看下面一段C#代码

using System;

using System.Collections.Generic;

using System.Text;

namespace FunctionTest

{

    class Program

    {

        static void Main(string[] args)

        {

            B b = new B();

            b.f(2);

            b.f(2, 3); // work well

        }

    }

    public class A

    {

        public void f(int x)

        {

            Console.WriteLine("A::f(int)");

        }

        public void f(int x, int y)

        {

            Console.WriteLine("A::f(int,int)");

        }

    }

    public class B : A

    {

        public void f(float x)

        {

            Console.WriteLine("B::f(float)");

        }

    }

}

 

执行结果是

B::f(float)

A::f(int,int)

此时为什么没有调用基类的函数呢 这与普通的函数重载肯定也有不同之处,我的理解是派生类中的函数会有比基类更高的优先级,int能直接转换为float型,然后进行调用,反之float转换成int,是不能隐式进行的,所以调用了基类的函数。这只是我的理解,如果有更好的解释情留言告诉我。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# c++ float string c