关于重载、隐藏、重写的一些思考(1)

来源:互联网 发布:java游戏聊斋聂小倩 编辑:程序博客网 时间:2024/06/11 09:10

开始这个问题之前,首先你要已经对于虚函数和虚函数表的概念有了一定得了解。

首先说一下重载(overload)这个概念,这很简单,在C语言里面就有的东西。

  • When two or more different declarations are specified for a single name in the same scope, that name is said to overloaded. By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations. Only function declarations can be overloaded; object and type declarations cannot be overloaded.

通常我们把同一作用域内,可以具有相同函数名,但是参数列表不同的函数,叫做重载函数。

void func1();void func1(int)

好,这so easy!

隐藏(namehiding),这是一个作用域的概念,这一点很重要。我们最早知道作用域这个概念,大概是C语言时期。

int x;void func(){    double x;    printf("%lf", x);}

我们可以很清晰的知道,double x 是local的,int x 是global的。接着我们考虑继承问题。

class Base{public:    virtual void func1() = 0;    virtual void func2();    virtual void func2(int);    //重载    void func3();    void func3(int);            //重载};class Derived: public Base{public:    virtual void func1();    void func3();    void func4();};

首先,Base::func1是一个纯虚函数,所以我们要在派生类中却实现它Derived::func1()。我们知道Base::func2这里发生了函数重载,Base::func2()Base::func2(int)在同一作用域内,函数名相同,但是参数列表不同。同样的Base::func3也发生了重载。

再看Base::func3Derived::func3,它们在不同作用域内。我们看到这里func3和前面说的x是不是有什么相似的点呢?对,它们的作用域都有一个包含的关系。



注意着张图的画法,要将此和继承的概念区分开,继承的话是Derived包含了Base。好的,我们看看结果是不是和我么想的一样。

Derived d;int x;d.func1();      //调用Derived::func1()d.func2();      //调用Base::func2()d.func3();      //调用Derived::func3()d.func3(x);     //出错,无法调用Base::func3(int)

果然如此,事实也确实如此。所以只要作用域之间是一种包含关系,不同作用域相同函数名函数之间就会发生隐藏

再来看重写(override)的问题,父类和子类函数都是virtual函数并且函数名和参数列表都相同,则它们构成的关系叫做override。

细心的同学一定注意到了上面Derived类里面似乎少了些什么。对,我们没有对于虚函数func2进行隐藏

class Base{public:    virtual void func1() = 0;    virtual void func2();    virtual void func2(int);    //重载    void func3();    void func3(int);            //重载};class Derived: public Base{public:    virtual void func1();    virtual void func2();       //新加的    void func3();    void func4();};

此时按照override的定义,可以很清楚地知道Base::func2Derived::func2构成override关系。

那这个override和namehiding有什么关系吗?它们看上去如此的相似。请看关于重载、隐藏、重写的一些思考(2)。