1:名称遮盖
名称遮盖就是子类中声明的函数名与父类中声明的函数名相同(返回值,参数类型和个数同于不同无关紧要,函数是否为虚也无关紧要),子类对象访问不到父类所定义的同名函数。
示例1:
#include <iostream.h>
class B
{
public:
void fun1()
{
cout<<"B::fun1"<<endl;
}
};
class D:public B
{
public:
void fun1(int )
{
cout<<"D::fun1 int"<<endl;
}
};
void main()
{
D d;
d.fun1();
}
上述代码回报错:error C2660: 'fun1' : function does not take 0 parameter
将函数改成virtual 也一样。
2:虚函数
虚函数的定义上上很多,不再赘述。这里想讨论一下虚函数的访问。
示例2:
#include <iostream.h>
class B
{
public:
void fun1()
{
cout<<"B::fun1"<<endl;
}
};
class D:public B
{
public:
virtual void fun1(int )
{
cout<<"D::fun1 int"<<endl;
}
virtual void fun1( )
{
cout<<"D::fun1"<<endl;
}
};
void main()
{
D d;
d.fun1();
B * pB=&d;
pB->fun1();
}
结果为:
D::fun1
B::fun1
表明在编译器内并不是直接查找虚函数表,来判断fun1是否在虚函数表中。就我而言,编译器会根据静态类型(B)判断虚函数表的哪些函数,指针(pB)可以访问。此例中基类B并没有虚函数,故pB不会去访问虚函数表,进而不会访问虚函数表中的fun1。
示例3:
#include <iostream.h>
class B
{
private: //注意访问权限
virtual void fun1()
{
cout<<"B::fun1"<<endl;
}
};
class D:public B
{
public:
virtual void fun1(int )
{
cout<<"D::fun1 int"<<endl;
}
virtual void fun1( )
{
cout<<"D::fun1"<<endl;
}
};
void main()
{
D d;
d.fun1();
B * pB=&d;
pB->fun1();//不可访问
}
pB->fun1()的访问级别受静态类型(B)的限制。
示例4:
#include <iostream.h>
class B
{
public:
virtual void fun1()
{
cout<<"B::fun1"<<endl;
}
};
class D:public B
{
private://注意访问权限
virtual void fun1(int )
{
cout<<"D::fun1 int"<<endl;
}
virtual void fun1( )
{
cout<<"D::fun1"<<endl;
}
};
void main()
{
D d;
// d.fun1();
B * pB=&d;
pB->fun1();
}
结果:D::fun1
通过父类指针(pB)访问到了子类的私有成员。说明函的访问权限由静态类型确定。
以上示例只是用于语法测试,没有考虑现实中面向对象设计所应该遵循的原则。如有错误,望君赐教。