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

浙公网安备 33010602011771号