第十三章 虚函数

第十三章 虚函数

1.  指向对象的指针

常用father *pfather=new son;

不常用son *pson=new son;?????????

2.  虚函数

覆盖 体现虚函数的多态性(动态联编)

基类指针存储不同对象调用不同类的函数

5.  在编译时的静态联编

6.  在运行时的静态联编

7.  在运行时的动态联编(耗时)

动态联编体现了多态性 所以一定要有virtual 而且要用指针或者别名 否则不能实现

8.  在编译时的动态联编

9.  三种调用虚函数的方式比较

要想显示virtual

存储不同对象的指针调用不同类的函数

②声明: 调用:  第一个按对象传递调用 不能呈现多态性。 按指针或引用传递 能呈现多态性

10.  系统是如何调用虚函数的

11.  在虚函数中使用成员名限定 

在虚函数中使用成员名限定可以强行解除动态联编

12.  构造函数和虚析构函数

如果基类中定义了虚函数,那么也要有虚析构函数。这样对内存的回收就会更准确些(一般都在基类加virtual)

没有虚构造函数

13.  纯虚函数

纯虚函数就是基类只定义了函数体,没有实现过程,定义方法如: virtual void Eat() = 0; 不要 cpp中定义;纯虚函数相当于接口,不能直接实例化,需要派生类来实现函数定义;

带纯虚函数的类叫虚基类,这种基类不能直接生成对象,而只有被继承,并重写其虚函数后,才能使用。这样的类也叫抽象类。 

虚函数是为了继承接口和默认行为

纯虚函数只是继承接口,行为必须重新定义

本章总结:

1.  动态联编(速度慢)(运行后才能确定指针指向那个对象)            静态联编(速度快)(编译后就能确定指针指向那个对象)

2.  只有基类virtual、父类指针、不同new类          的连用才能体现多态性

3.  成员名限定符可以强制解除动态联编p->Fahter::get();

4.  有虚函数,就要有虚析构函数(注意:只要看到派生类,不论有无虚函数,都要有虚析构函数)

5.  虚函数、虚析构函数virtual都设在基类

  1 /**
  2 运行时的动态联编
  3 动态联编体现了多态性,一定要用virtual和指针,才能展示*******************①
  4 */
  5 
  6     
  7 //#include"iostream"
  8 //using namespace std;
  9 //class Father
 10 //{
 11 //public:
 12 //    Father(){cout<<"Father";}
 13 //    virtual int get(){return 1;}
 14 //
 15 //};
 16 //class Son:public Father
 17 //{
 18 //public:
 19 //    Son(){cout<<"Son";}
 20 //    int get(){return 2;}
 21 //};
 22 //int main()
 23 //{
 24 //    while(1)
 25 //    {
 26 //        bool x=false;
 27 //        Father *P;
 28 //        bool quit=false;
 29 //        do
 30 //        {            
 31 //            x=false;
 32 //            cout<<"(1)父类(2)子类(3)退出:";
 33 //            int choice;
 34 //            cin>>choice;
 35 //            
 36 //            switch(choice)
 37 //            {
 38 //            case 1:P=new Father;
 39 //                  break;
 40 //            case 2:P=new Son;
 41 //                  break;
 42 //            case 3:quit=true;
 43 //                  break;
 44 //            default:cout<<"请输入进行选择:
";x=true;
 45 //                  break;
 46 //            }
 47 //        }while(x==true);
 48 //            
 49 //        if(quit==true)//如果误写成quit=true那就直接运行了
 50 //        {
 51 //            break;
 52 //        }
 53 //        else 
 54 //        {
 55 //            cout<<P->get()<<endl;
 56 //            delete P;
 57 //            P=NULL;        
 58 //        }
 59 //        
 60 //    }
 61 //
 62 //    return 0;
 63 //}
 64 
 65 
 66 
 67 
 68 //#include"iostream"
 69 //using namespace std;
 70 //class A
 71 //{
 72 //public:
 73 //    virtual void one(){cout<<"one"<<endl;two();};
 74 //    //此处一个virtual就可以了,因为以后的函数都有one间接调用************************②
 75 //    void two(){cout<<"two"<<endl;three();}
 76 //    void three(){cout<<"three"<<endl;four();}
 77 //    void four(){cout<<"three"<<endl;five();}
 78 //    void five(){cout<<"three"<<endl;}    
 79 //};
 80 //class B:public A
 81 //{
 82 //public:
 83 //    void one(){cout<<"1"<<endl;two();};
 84 //    void two(){cout<<"2"<<endl;three();}
 85 //    void three(){cout<<"3"<<endl;four();}
 86 //    void four(){cout<<"4"<<endl;five();}
 87 //    void five(){cout<<"5"<<endl;}
 88 //};
 89 //class C:public A
 90 //{
 91 //public:
 92 //    void one(){cout<<"一"<<endl;two();};
 93 //    void two(){cout<<"二"<<endl;three();}
 94 //    void three(){cout<<"三"<<endl;four();}
 95 //    void four(){cout<<"四"<<endl;five();}
 96 //    void five(){cout<<"五"<<endl;}
 97 //};
 98 //int main()
 99 //{
100 //    A *p;
101 //    int choice;
102 //    bool quit=false;
103 //    int x;
104 //    while(1)
105 //    {
106 //        do
107 //        {
108 //            x=0;
109 //            cout<<"(0)退出(1)英文(2)阿拉伯文(3)中文"<<endl;
110 //            cin>>choice;
111 //            switch(choice)
112 //            {
113 //            case 0:cout<<"退出程序"<<endl;quit=true;
114 //                break;
115 //            case 1:cout<<"英文:"<<endl;p=new A;
116 //                break;
117 //            case 2:cout<<"阿拉伯文:"<<endl;p=new B;
118 //                break;
119 //            case 3:cout<<"中文:"<<endl;p=new C;
120 //                break;
121 //            default:cout<<"请做出正确选择:"<<endl;x=1;
122 //            }
123 //        }while(x==1);
124 //        if(quit)
125 //            break;
126 //        else
127 //        {
128 //            p->one();
129 //            //p->A::one();//成员限定符能强制解除动态联编
130 //            delete p;
131 //            p=NULL;
132 //        }
133 //    }
134 //    return 0;
135 //}
136 
137 
138 
139 
140 //有virtual函数就要有virtual析构函数
141 #include"iostream"
142 using namespace std;
143 class A
144 {
145 public:
146     A(){cout<<"A类的构造函数"<<endl;}//构造函数没有虚函数****************③
147     void fun(){cout<<"类A的fun()函数"<<endl;}
148     virtual ~A(){cout<<"A类的析构函数"<<endl<<endl;}
149 };
150 class B:public A
151 {
152 public:
153     B(){cout<<"B类的构造函数"<<endl;}
154     void fun(){cout<<"类B的fun()函数"<<endl;}
155     ~B(){cout<<"B类的析构函数"<<endl;}
156 };
157 int main()
158 {
159     A *pa=new A;
160     pa->fun();
161     delete pa;
162     pa=NULL;
163 
164     A *pb=new B;//用指向B类的A类指针调用重载函数,基类的析构函数要设为虚函数*********************④
165     pb->fun();
166     delete pb;
167     pb=NULL;
168     return 0;
169 }
原文地址:https://www.cnblogs.com/zenseven/p/3735039.html