#include <iostream>
using namespace std;
class Base{
protected:
int n;
public:
Base (int m){ n=m++; }
virtual void g1(){cout<<"Base::g1()..."<<n<<endl; g4();}
virtual void g2(){cout<<"Base::g2()..."<<++n<<endl;g3();}
virtual void g3(){cout<<"Base::g3()..."<<++n<<endl; g4();}
virtual void g4(){cout<<"Base::g4()..."<<++n<<endl;}
};
class Derive:public Base{
int j;
public:
Derive(int n1,int n2):Base(n1){ j=n2; }
void g1(){cout<<"Deri::g1()..."<<++n<<endl;g2();}
void g3(){cout<<"Deri::g2()..."<<++n<<endl;g4();}
};
void main(){
Derive Dobj(1,0);
Base Bobj=Dobj;
Bobj.g1();
cout<<"------------------"<<endl;
Base *bp=&Dobj;
bp->g1();
cout<<"------------------"<<endl;
Base &bobj2=Dobj;
bobj2.g1();
cout<<"------------------"<<endl;
Dobj.g1();
}
输出的结果如上。
我们需要对每一个代码进行分析
(1)
Derive Dobj(1,0); //L1
Base Bobj=Dobj; //L2
<pre name="code" class="cpp"> Bobj.g1(); //L3
L1 创建一个Derive类的对象Dobj,并通过构造函数,对其赋值。L2创建一个Base类的对象Bobj,并将Dobj赋值给Bobj,因为这其中涉及到了基类对象和派生类对象赋值之间的问题,派生类对象赋值给基类对象,只会把基类部分的值赋给基类对象,也就是说由派生类自己定义的成员是无法赋值到基类对象中。因此就不能解释L3的结果了,当调用g1()时,并没有调用到Derive中的g1(),而是基类中的g1().
(2)
Base *bp=&Dobj; //L1
bp->g1(); //L2
L1创建一个Base类的名为bp指针,并指向Dobj的地址。通过bp指针调用g1()函数,根据通过基类对象的指针和引用访问派生类对象的虚函数时,会体现虚函数的特性。调用g1()时,实际上就是调用Derive中的g1(),并输出结果。输出结果后,g1()函数后继续调用g2(),因为Derive中并没有g2()函数,因此会自动调用Base中的g2(),输出结果,继续调用g2()中的g3()。注意:派生类通过从基类继承的成员函数调用虚函数时,将访问到派生类中的版本,例子如下:
#include<iostream>
using namespace std;
class B
{
public:
void f(){g();}
virtual void g(){cout<<"B::g";}
};
class D:public B
{
public:
void g(){cout<<"D::g";}
};
void main()
{
D d;
d.f();
}
因此将调用Derive中的g3(),输出并继续调用Base中的g4();
后面的调用如上~~~