虚函数(二)

来源:互联网 发布:数据库sql语句在哪 编辑:程序博客网 时间:2024/06/05 09:14
#include<iostream>  #include<vector>  #include<string>  using namespace std;  //基类A  class A  {  public:      A()      {          printf("A constructed.\n");      }      virtual ~A()      {          printf("A deconstructef.\n");      }      virtual void fn()      {          printf("A fn called.\n");      }      void fn2(void)      {          printf("A fn222 called.\n");      }  };  //派生类B,公有继承自基类A  class B:public A  {  public:      B()      {          printf("B constructed.\n");      }      virtual ~B()      {          printf("B deconstructef.\n");      }      virtual void fn()      {          printf("B fn called.\n");      }      void fn2(void)      {          printf("B fn222 called.\n");      }  };  //多层派生  //派生类C,公有继承自基类B,而基类B,公有继承自基类A  class C :public B  {  public:      C()      {          printf("C constructed.\n");      }      virtual ~C()      {          printf("C deconstructef.\n");      }      virtual void fn()      {          printf("C fn called.\n");      }      void fn2()      {          printf("C fn222 called.\n");      }  };  //main函数  int main()  {      A *pA = new B;      //基类A的指针指向派生类B(新生成的一个派生类B)所以:先调用了A类的构造函数(输出"A constructed."),      //然后调用了派生类B的构造函数(输出"B constructed.")。      if (pA != NULL)     //条件满足,故执行:      {          pA->fn();    //fn()是被重定义的虚函数,根据指针所指对象来调用,所以调用类B的fn2()函数(输出"B fn called")。          pA->fn2();   //fn2()是非虚函数,根据指针类型来调用:pA是类A的指针,所以调用类A的fn2()函数(输出"A fn222 called")。      }      B *pB = static_cast<B*>(pA);      //将基类A的指针pA强制转换为派生类B的指针pB(下行转换必须显示声明)      //还记得吗?(上行转换的效果;类似于多态。但,下行转换,效果正好相反!)      if (pB != NULL)     //条件满足,故执行:      {          pB->fn();    //fn()是被重定义的虚函数,根据指针所指对象来调用,所以调用类B的fn2()函数(输出"B fn called")。          pB->fn2();   //fn2()是非虚函数,根据指针类型来调用:pB是类B的指针,所以调用类B的fn2()函数(输出"B fn222 called")。      }      C *pC = static_cast<C*>(pA);      //将基类A的指针pA强制转换为派生类C的指针pC(下行转换必须显示声明)      if (pC != NULL)     //条件满足,故执行:      {          pC->fn();    //fn()是被重定义的虚函数,根据指针所指对象来调用,所以调用类B的fn2()函数(输出"B fn called")。          pC->fn2();   //fn2()是非虚函数,根据指针类型来调用:pC是类C的指针,所以调用类C的fn2()函数(输出"C fn222 called")。      }      delete pA;          //由于是基类A是虚析构函数,故牵扯到对象的完全释放:                          //先执行B的析构函数输出(B deconstructef.),再执行A的析构函数输出(A deconstructef.)。      system("pause");      return 0;  }  /* A constructed. B constructed. B fn called A fn222 called B fn called. B fn222 called B fn called. C fn222 called B deconstructef. A deconstructef. */