今天看到一个有意思的C++语法问题。就是如果一个派生类中含有与基类虚函数重名的静态成员函数,用指针调用会如何。代码如下:
using namespace std;
class A
{
public :
void virtual print(){ cout<<"A::print()"<< endl; }
};
class B :public A
{
public :
void virtual print(){ cout<<"B::print()"<< endl; }
} ;
class C :public B
{
public :
static void print(){ cout<<"C::print()"<< endl; }
} ;
void print (A a)
{
a.print();
}
void main()
{
A a, *aa, *ab, * ac;
B b;
C c;
aa=& a;
ab=& b;
ac=& c;
//c.print();
ac-> print();
}
大家可以猜猜结果。
================================
【答案】
B::print()
【我的分析】
在调用函数时,当然会先进行名字查找,根据ac的静态类型,那么肯定是A了,在A的作用域中找到了名为print()的函数,查找结束。进行圆形匹配,发现也是匹配的。然后因为ac是指针,调用函数时发生动态绑定,而C类含有虚函数表。所以应该先去C类的虚函数表中查找print(),但是C类的虚函数表其实是跟B类一样的(因为C类并没有增添任何的虚函数)。这个时候当然只找得到B::print了。
但是如果是使用对象调用,如c.print(),不是动态绑定的,那还是会调用C::print。参见注释的一行。
当然编译器给出了一个警告:静态函数是不能用作虚函数进行调用的(MSVC:warning c4526)。