1.当由指针调用由子类(或某一个类)实例化的对象时(不管此指针是指向谁的那个类型的,只要合法),当指针调用此对象中的函数时(不管是子类中添加的还是由父类继承来的),如果此函数是非虚拟函数,则首先在那个类中寻找这个函数,若找不到则依次向父类中寻找,直至找到(如果找不到,那此程序就出错了,呵呵),但不会向下向子类中寻找;如果此函数是虚拟函数,则就要严重关注此实例化对象,不管是先前指针所指向的还是后来又实例化的,具体情况具体分析(废话)(依次严重关注调用函数所属于的实例化的对象),要在某类中调用某函数时要追本溯源,重新返回产生对象的那个类(可能是最后的子类),再依次向父类寻找(不要懒,呵呵),看看到底是属于哪个类的,而不要被函数所在的位置所迷惑,实际有可能要调用的函数在子类,本类或父类中。(注:如果调用函数的前面指明调用属于哪个类那个域的函数,没办法,只有调用那个类的了。如:CWinThread::Run(),只有调用CWinThread类中的Run()函数了)
附两个小程序以供参考调试:
a)非虚拟函数:
#include<iostream.h>
class CBase
{
public:
void Init()//virtual
{
cout << "CBase::Init()" << endl;
}
void fun()//virtual
{
cout << "CBase::fun()" << endl;
}
};
class CChild1 : public CBase
{
public:
void Init()//virtual
{
cout << "CChild1::Init()" << endl;
}
void fun()
{
cout << "CChild1::fun()" << endl;
}
};
class CChild2 : public CChild1
{
public:
void Init()//virtual
{
cout << "CChild2::Init()" << endl;
fun();
}
void fun()
{
cout << "CChild2::fun()" << endl;
}
};
class CChild3 : public CChild2
{
public:
CChild3()
{
Init();
}
void fun()
{
cout << "CChild3::fun()" << endl;
}
};
void main()
{
CChild3* m_pCurrent = NULL;
m_pCurrent = new CChild3;
}
输出:
CChild2::Init()
CChild2::fun()
b)虚拟函数:
#include<iostream.h>
class CBase
{
public:
void Init()//virtual
{
cout << "CBase::Init()" << endl;
}
virtual void fun()//
{
cout << "CBase::fun()" << endl;
}
};
…………………
……………………//下面完全跟非虚拟函数的相同,二者区别只是在虚拟函数中的类CBase中fun()函数前加了一个virtual关键字而已。
输出:
CChild2::Init()
CChild3::fun()
-------------------------------------------------------------------------