虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底

为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针。

也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual

 1 #include<iostream>
 2 using namespace std;
 3
 4 class base{
 5 public:
 6     /*virtual*/ void who(){    //define this function to virtual will be normal
 7         cout << "this is the class of base !" << endl;
 8     }
 9 };
10
11 class derive1:public base{
12 public:
13     void who(){
14         cout << "this is the class of derive1 !" << endl;
15     }
16 };
17 class derive2 :public base{
18 public:
19     void who(){
20         cout << "this is the class of derive2 !" << endl;
21     }
22 };
23 int main(){
24     base beseObject, *p;
25     derive1 obj1;
26     derive2 obj2;
27     p = &beseObject;
28     p->who();
29     cout << "------------------------------" << endl;
30     p = &obj1;
31     p->who();
32     ((derive1*)p)->who();
33     cout << "------------------------------" << endl;
34     p = &obj2;
35     p->who();
36     ((derive2*)p)->who();
37     cout << "------------------------------" << endl;
38     obj1.who();
39     obj2.who();
40     int i;
41     cin >> i;
42     return 0;
43 }

两次结果比较: 没加virtual:;加virtual后:

与重载的关系:

 1 #include<iostream>
 2 using namespace std;
 3
 4 class base{
 5 public:
 6     virtual void f1(){    //virtual function
 7         cout << "f1 function of base " << endl;
 8     }
 9     virtual void f2(){    //virtual function
10         cout << "f2 function of base " << endl;
11     }
12     virtual void f3(){    //virtual function
13         cout << "f3 function of base " << endl;
14     }
15     void f4(){
16         cout << "f4 function of base " << endl;
17     }
18 };
19
20 class derive:public base{
21 public:
22     void f1(){    //virtual function
23         cout << "f1 function of derive " << endl;
24     }
25     virtual void f2(int x){    //lose virtual characteristic
26         cout << "f2 function of derive " << endl;
27     }
28     //f3(){    //wrong, not the same return type
29     //    cout << "f3 function of base " << endl;
30     //}
31     void f4(){    //normal overload
32         cout << "f4 function of derive " << endl;
33     }
34 };
35 int main(){
36     base obj1, *ptr;
37     derive obj2;
38     ptr = &obj1;
39     ptr->f1();
40     ptr->f2();
41     ptr->f3();
42     ptr = &obj2;
43     ptr->f1();
44     ptr->f2();
45     ptr->f4();
46     int i;
47     cin >> i;
48     return 0;
49 }

结果:

空虚函数在中间类里必须声明,以保证其后的派生类能使用该虚函数。建立一条从虚函数到派生类的虚函数路径。

 1 #include<iostream>
 2 using namespace std;
 3
 4 class base{
 5 public:
 6     virtual void print(){
 7         cout << "calss base!" << endl;
 8     }
 9 };
10 class son:public base{
11 public:
12     virtual void print(){ //empty virtual class
13     }
14 };
15 class grandson :public son{
16 public:
17     void print(){
18         cout << "calss grandson!" << endl;
19     }
20 };
21 void show(base* b){
22     b->print();
23 }
24 int main(){
25     base *pbase = new base;
26     son *pson = new son;
27     grandson *pgrandson = new grandson;
28     show(pbase);
29     show(pson);
30     show(pgrandson);
31     int i;
32     cin >> i;
33     return 0;
34 }

结果:

存虚函数与抽象类

 1 #include<iostream>
 2 using namespace std;
 3
 4 class shape{  //抽象类里必须有一个纯虚函数
 5 public:
 6     virtual float area() = 0;
 7 };
 8 class triangle :public shape{
 9 protected:
10     float h, w;
11 public:
12     triangle(float hh, float ww){
13         h = hh; w = ww;
14     }
15     float area(){
16         return h*w*0.5;
17     }
18 };
19 class rectangle :public shape{
20 protected:
21     float h, w;
22 public:
23     rectangle(float hh, float ww){
24         h = hh; w = ww;
25     }
26     float area(){
27         return h*w;
28     }
29 };
30 float total(shape* s[], int n){
31     float sum = 0;
32     for (int i = 0; i < n - 1; i++)
33         sum += s[i]->area();
34     return sum;
35 }
36 int main(){
37     shape* s[2];
38     s[0] = new triangle(3, 4);
39     s[1] = new rectangle(3, 4);
40     float sum = total(s, 2);
41     cout <<"total area is: "<< sum << endl;;
42     int i;
43     cin >> i;
44     return 0;
45 }

结果:算出总面积 为 6

虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底

时间: 2024-08-02 17:19:57

虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底的相关文章

为什么基类的析构函数是虚函数?

1.第一段代码 #include<iostream> using namespace std; class ClxBase{ public: ClxBase() {}; ~ClxBase() { cout << "Output from the destructor of class ClxBase!" << endl; }; void DoSomething() { cout << "Do something in class

构造函数为什么不能为虚函数 &amp;amp; 基类的析构函数为什么要为虚函数

一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数是虚的,就须要通过 vtable来调用,但是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到相应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚

构造函数为什么不能为虚函数 &amp; 基类的析构函数为什么要为虚函数

一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函

C++虚函数的陷阱--派生类对象的基类函数调用基类虚函数出错

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近写程序的时候发现,派生类对象的基类函数如果调用基类虚函数,则它将调用的是派生类的对应函数,而不是我想调用的基类的对应函数.</span> 下面用一个例子来说明: //基类 class Base { public: void funA(); virtual void fun

C++ 为什么设置基类的析构函数为虚函数

对象的析构函数调用顺序是从派生类到基类 那么如果基类的指针指向派生类的对象 还能正常的执行析构顺序吗 下面看一个类的声明 class Subject { public: ~Subject(); Subject(); }; class ConcreteSubject : public Subject { public : ConcreteSubject(); ~ConcreteSubject(); }; 创建基类的指针 并删除该对象 Subject * con = new ConcreteSubj

C++ 设置基类的析构函数为虚函数

析构函数是当一个对象的生命周期结束时自动调用的一个函数. 在下面的函数中,执行后会发现只有基类的析构函数被调用了,派生类的析构函数并没有被调用,导致对象没有被正常的释放,导致内存泄漏. 把基类的析构函数设置为虚函数,在执行动态调用时就会执向对象的析构函数. class Subject { public: ~Subject(); Subject(); }; class ConcreteSubject : public Subject { public : ConcreteSubject(); ~C

从为什么要将基类的析构函数定义为虚函数谈起~~

 首先,做一个最简单的实验,在电脑上运行下面的代码,将会产生运行错误,这或许会使你百思不得其解: #include <iostream> using namespace std; class Base { private: int a; public: ~Base(){cout << "Base dtor..." << endl;} }; class Derived : public Base { private: int b; public: ~D

为什么基类的析构函数要写成虚函数?

为什么基类的析构函数要写成虚函数? 答:在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生. 代码说明如下 第一段代码: 1 #include<iostream> 2 using namespace std;   3    4 class ClxBase   5 {public:   6 ClxBase() {}   7 ~ClxBase() {cout << "Output from the destructor of class ClxB

C++中基类的析构函数为什么要用virtual虚析构函数

知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放.假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数.那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏