In fact, similar questions were asked here and there, but the answers were not satisfied. The code example is
class CBase
{
public:
virtual void act1(){cout<<"CBase::act1()! "<<endl; act2();}
void act2() {cout<<"CBase::act2()! "<<endl; act3();}
virtual void act3(){cout<<"CBase::act3()! "<<endl; act4();}
virtual void act4(){cout<<"CBase::act4()! "<<endl; act5();}
void act5() {cout<<"CBase::act5()! "<<endl; }
virtual ~CBase(){}
} ;
class CDerive : public CBase
{
public:
void act3(){cout<<"CDerive::act3()! "<<endl; act4();}
void act4(){cout<<"CDerive::act4()! "<<endl; act5();}
void act5(){cout<<"CDerive::act5()! "<<endl; }
virtual ~CDerive(){}
} ;
int main()
{
CBase *p=new CDerive;
p->act1();
cout<<endl;
p->act5();
delete p;
return 0;
}
and the output is
CBase::act1()!
CBase::act2()!
CDerive::act3()!
CDerive::act4()!
CDerive::act5()!
CBase::act5()!
With respect to p->act1()
- since
act1()is a virtual function and derived class doesn't implement it, the program will callCBase::act1(); - then program will call
CBase::act2(); act3()is a vritual function, the program will callCDervie::act3();act4()is also a vritual function, the program will callCDervie::act4();- here comes the part that I don't understand,
act5()is not a virtual function, andpis a pointer belonging toCBase, basicallypcan only access the function inCBase! But the output isCDerive::act5()!
In contrast, p->act5() will call CBase::act5() as I think.
There seems to be contradictory between the principle - the base class pointer can only access the function defined in base class and virtual function, and the real output. The reason can't be explained from virtual table either, since CDerive::act5() is not even in the virtual table. So, my questions are
- what is the rationale behind those ?
- what did happen when
CBase *p=new CDeriveorCDerive a; CBase *p=&a?
act5fromCDerive::act4... static type is soCDerive.pthat accessesact5, but theCDeriveinstance itself, insideCDerive::act4. When you call a non-virtual member function from another member function, it is selected based on the static type of*thisin that member function.