c++的多态

来源:互联网 发布:flexible.js原理 编辑:程序博客网 时间:2024/06/08 12:22

转自:http://blog.csdn.net/user_define_race/article/details/46277213?locationNum=2&fps=1

[cpp] view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3. //赋值兼容性原则(把子类对象赋给父类指针或引用)  
  4. //函数重写   
  5. //这就是面向对象的新需求  
  6. //如果传来子类对象,那么执行子类函数  
  7. //多态  c++ 编译器提供的多态方案是虚函数  
  8. class Parent  
  9. {  
  10. public:  
  11.     Parent(int a=0)  
  12.     {  
  13.         this->a=a;  
  14.     }  
  15.     virtual void print()  
  16.     {  
  17.        cout<<"a"<<a<<endl;  
  18.     }  
  19. private :  
  20.     int a;  
  21. };  
  22. class Child: public Parent  
  23. {  
  24. public:  
  25.     Child(int b=0)  
  26.     {  
  27.       this->b=b;  
  28.   
  29.     }  
  30.     void print()  
  31.     {  
  32.        cout<<"b"<<b<<endl;  
  33.     }  
  34. private:  
  35.     int b;  
  36. };  
  37. //c++ 是默认是静态编译语言,根据类型,去执行响应的函数 Parent  
  38. //言外之意;:c++ 根据指针类型,去决定到具体的类里面,执行相应操作  
  39. //如果基类中加上virtual 关键字 c++ 编译器会动手脚==》动态链接编译  
  40. //c++ 编译器会来一个迟绑定   
  41. void howtoPrint(Parent *base)  
  42. {  
  43.     base->print();  
  44. }  
  45.   
  46. void howtoPrint2(Parent & base)  
  47. {  
  48.     base.print();  
  49. }  
  50. void main()  
  51. {  
  52.     Parent p1;  
  53.     Child c1;  
  54.     /*p1.print(); 
  55.     c1.print();*/  
  56.       
  57.     Parent * base=NULL;  
  58.     base=&p1;  
  59.     base->print();//打印父类的  
  60.   
  61.     base=&c1;  
  62.     base->print();//打印父类的  
  63.     //p2 是c1 的别名,是c1本身  
  64.     Parent & p2=c1;  
  65.     p2.print();//打印父类的  
  66.     howtoPrint(&p1);  
  67.     howtoPrint(&c1);  
  68.   
  69.     howtoPrint2(p1);  
  70.     howtoPrint2(c1);  
  71.     //以上打印父类的  
  72.     system("pause");  
  73. }  
[cpp] view plain copy
  1. </pre><pre name="code" class="cpp">  



多态实例:

[cpp] view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3. class HeroFighter  
  4. {  
  5. public:  
  6.     virtual int Atack()  
  7.     {  
  8.        return 10;  
  9.     }  
  10. protected:  
  11. private:  
  12. };  
  13. class EmenyFighter  
  14. {  
  15. public :  
  16.     int DesoryPower()  
  17.     {  
  18.         return 15;  
  19.     }  
  20. };  
  21. class HeroAd2Fighter:public HeroFighter  
  22. {  
  23. public:  
  24.      int Atack()  
  25.     {  
  26.        return 20;  
  27.     }  
  28. protected:  
  29. private:  
  30. };  
  31.   
  32. void ObjFighter(HeroFighter * pbase,EmenyFighter * emeny )  
  33. {  
  34.     if(pbase->Atack()>emeny->DesoryPower())  
  35.     {  
  36.         printf("主角win\n");  
  37.     }else{  
  38.         printf("主角挂了\n");  
  39.     }  
  40. }  
  41. void main2()  
  42. {  
  43.     HeroFighter h1;  
  44.     EmenyFighter e1;  
  45.     HeroAd2Fighter hadv;  
  46.     if(h1.Atack()>e1.DesoryPower())  
  47.     {  
  48.         printf("主角win\n");  
  49.     }else{  
  50.         printf("主角挂了\n");  
  51.     }  
  52.   
  53.     if(hadv.Atack()>e1.DesoryPower())  
  54.     {  
  55.         printf("主角win\n");  
  56.     }else{  
  57.         printf("主角挂了\n");  
  58.     }  
  59.     system("pause");  
  60. };  
  61. void main()  
  62. {  
  63.     HeroFighter h1;  
  64.     EmenyFighter e1;  
  65.     HeroAd2Fighter hadv;  
  66.     ObjFighter(&h1,&e1);  
  67.     ObjFighter(&hadv,&e1);  
  68. };  


virtual 实现多态,c++ 编译器应该动什么手脚。

第一个需要动手脚的地方  起码这个函数print 我应该动什么手脚

我怎么知道是父类对象还是子类对象?

区分是父类对象还是子类对象0


 当类中声明虚函数时,编译器会在类中生成一个虚函数表。

虚函数表是一个存储类成员函数指针的数据结构

虚函数表是由编译器放入虚函数表中

存入虚函数时,每个对象中都有一个指向虚函数表的指针(vptr 指针)








[cpp] view plain copy
  1. #include "iostream"  
  2.   
  3. using namespace std;  
  4.   
  5. class AA  
  6. {  
  7. public:  
  8.     AA(int a= 0)  
  9.     {  
  10.         this->a = a;  
  11.         print(); //在构造函数里面能实现多态吗?  
  12.     }  
  13.   
  14.     //分析一下要想实现多态,c++编译器应该动什么手脚  
  15.     //第一个需要动手脚的地方  起码这个函数print 我应该特殊处理  
  16.     virtual void print()  
  17.     {  
  18.         cout<<"父类的"<<"a"<<a<<endl;  
  19.     }  
  20. protected:  
  21.     int a ;  
  22. };  
  23.   
  24. class BB : public AA  
  25. {  
  26. public:  
  27.     BB(int a= 0, int b = 0)  
  28.     {  
  29.         this->a = a;  
  30.         this->b = b;  
  31.       
  32.     }  
  33.     virtual void print()  
  34.     {  
  35.         cout<<"子类的"<<"a"<<a<<"b"<<b<<endl;  
  36.     }  
  37. private:  
  38.     int b ;  
  39. };  
  40.   
  41.   
  42. void howToPrintf(AA *pBase)  
  43. {  
  44.     //pBase 我怎么知道是父类对象还是子类对象  
  45.     //动手脚2::区分是父类对象还是子类对象,提前布局  
  46.     pBase->print();  //  
  47. }  
  48. void main()  
  49. {  
  50.     //AA a1;  
  51.     BB b1;  
  52.     //howToPrintf(&a1);  
  53.     howToPrintf(&b1);  
  54.     system("pause");  
  55. }  



[cpp] view plain copy
  1. #include "iostream"  
  2. using namespace std;  
  3.   
  4. //指针也是一种数据类型,指针数据的数据类型是指,它所指的内存空间的数据类型  
  5. //最后一点引申 指针的步长 。。。c++  
  6.   
  7. class Parent01  
  8. {  
  9. protected:  
  10.     int i;  
  11.     int     j;  
  12. public:  
  13.     virtual void f()  
  14.     {  
  15.         cout<<"Parent01::f"<<endl;  
  16.     }  
  17. };  
  18.   
  19.   
  20. class Child01 : public Parent01  
  21. {     
  22. public:  
  23.     int k;  
  24. public:  
  25.     Child01(int i, int j)  
  26.     {  
  27.         printf("Child01:...do\n");  
  28.     }  
  29.   
  30.     virtual void f()  
  31.     {  
  32.         printf("Child01::f()...do\n");  
  33.     }  
  34. };  
  35.   
  36. void howToF(Parent01 *pBase)  
  37. {  
  38.     pBase->f();  
  39. }  
  40.   
  41. //指针的步长 在c++领域仍然有效,父类指针的步长和子类指针的步长不一样  
  42. //多态是靠迟绑定实现的(vptr+函数指针实现)  
  43. int main06()  
  44. {  
  45.     int i = 0;  
  46.     Parent01* p = NULL;  
  47.     Child01* c = NULL;  
  48.   
  49.     //不要把父类对象还有子类对象同事放在一个数组里面  
  50.     Child01 ca[3] = {Child01(1, 2), Child01(3, 4), Child01(5, 6)};  
  51.   
  52.     //不要用父类指针做赋值指针变量,去遍历一个子类的数组。  
  53.   
  54.     p = ca;  
  55.     c = ca;  
  56.   
  57.     p->f();  
  58.     c->f(); //有多态发生  
  59.   
  60. //  p++;  
  61. //  c++;  
  62. //   
  63. //  p->f();//有多态发生  
  64. //  c->f();  
  65.   
  66.     for (i=0; i<3; i++)  
  67.     {  
  68.         howToF(&(ca[i]));  
  69.     }  
  70.   
  71.       
  72.     system("pause");  
  73.     return 0;  
  74. }  

原创粉丝点击