C++ 遮蔽

函数遮蔽同样要求构成继承关系,构成继承关系的两个类中具有相同函数名的函数,如果这两个函数不够成覆盖关系,则就构成了遮蔽关系。遮蔽理解起来很简单,只要派生类与基类中具有相同函数名(注意不是相同函数签名,只需要相同函数名就可以了)并且不构成覆盖关系即为遮蔽。

遮蔽可以分为两种情况,一种是非虚函数之间,另一种则是虚函数之间。我们通过程序示例来分别介绍这两种遮蔽情况。

#include<iostream>
using namespace std;
class base
{
public :
    void vir1(){cout<<"base vir1"<<endl;}
    void vir2(){cout<<"base vir2"<<endl;}
};
class derived : public base
{
public:
    void vir1(){cout<<"derived vir1"<<endl;}
    void vir2(int){cout<<"derived vir2"<<endl;}
};
int main() {
    base *p;
    p = new derived;
    p->vir1();
    p->vir2();
    delete p;
    derived d;
    d.vir1();
    d.vir2(5);
    d.base::vir1();
    d.base::vir2();
    return 0;
}

在本例中没有虚函数,base 类和 derived 类构成继承关系,因为构成继承关系的两个类中有同名函数,因此构成了函数遮蔽:派生类中的 vir1() 函数遮蔽了基类中的 vir1() 函数,派生类中的 vir2() 函数遮蔽了基类中的 vir1() 函数。

再次强调,虽然派生类中的 vir2() 函数和基类中的 vir2() 函数的函数签名不同,但是只需要函数名相同就构成函数遮蔽。

紧接着分析一下主函数:

  • 先定义了基类类型的指针,指针指向的是基类对象,然后通过指针调用函数 vir1() 和 vir2(),这个时候因为并不构成多态,因此调用的还是基类的 vir1() 和 vir2() 函数。

  • 之后定义了一个派生类对象 d,通过该对象调用 vir1() 和 vir2() 函数,因为派生类中的 vir1() 和 vir2() 遮蔽了基类中的 vir1() 和 vir2() 函数,因此直接调用的将会是派生类中的 vir1() 和 vir2() 函数。这种情况下,如果需要通过派生类对象调用被遮蔽的基类中的函数,则需要通过::域解析操作符来处理,比如d.base::vir1();和d.base::vir2();就是这么做的。

这个程序的最终运行结果如下:

base vir1
base vir2
derived vir1
derived vir2
base vir1
base vir
posted @ 2022-08-19 22:47  luoganttcc  阅读(22)  评论(0)    收藏  举报