`

C++中的函数多态性应用&虚函数的灵活应用

阅读更多

一、多态性

   派生类对象可以替代基类对象为基类的引用初始化或赋值。

函数的多态性其实就是对函数不同形式的声明的一种灵活应用。比如说,我们同名不同参数的函数就是对函数的一种多态性表现;同名同参就是函数的覆盖;如果我们用不同类型的参数和个数来声明不同或相同的函数,那么程序会根据我们调用实参的个数和类型进行匹配调用之前声明的函数模型,进行运算求值。

 

二、虚函数

  在类的继承层次结构中,在不同的层次中可以出现同名同参(类型、个数)都相同的函数。在子类中调用父类的成员方法,可以使用子类对象调用时使用父类的作用域实现。

虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

举一个实例来说明使用虚函数与不使用虚函数的区别,基类和派生类中都有同名函数。

不使用虚函数:

 

 

 

  1. //  
  2. //  Student.h  
  3. //  Programs  
  4. //  
  5. //  Created by bo yang on 4/17/12.  
  6. //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #ifndef Programs_Student_h  
  10. #define Programs_Student_h  
  11. using namespace std;  
  12.   
  13. class Student  
  14. {  
  15. public:  
  16.     Student(int ,string,float);  
  17.     void display();  
  18. protected:  
  19.     int num;  
  20.     string name;  
  21.     float score;  
  22. };  
  23.   
  24.   
  25. #endif  

  1. //  
  2. //  Student.cpp  
  3. //  Programs  
  4. //  
  5. //  Created by bo yang on 4/17/12.  
  6. //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #include <iostream>  
  10. #include <string>  
  11. #include "Student.h"  
  12. using namespace std;  
  13.   
  14. //定义构造函数  
  15. Student::Student(int n,string nam,float s)  
  16. {  
  17.     num=n;  
  18.     name=nam;  
  19.     score=s;  
  20. }  
  21.   
  22. void Student::display()  
  23. {  
  24.     cout<<"num:"<<num<<"\n name:"<<name<<"\n score:"<<score<<"\n"<<endl;  
  25. }  

  1. //  
  2. //  Graduate.h  
  3. //  Programs  
  4. //  
  5. //  Created by bo yang on 4/17/12.  
  6. //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #ifndef Programs_Graduate_h  
  10. #define Programs_Graduate_h  
  11. #include "Student.h"  
  12. #include <string.h>  
  13. using namespace std;  
  14.   
  15. class Graduate:public Student  
  16. {  
  17. public:  
  18.     Graduate(int ,string ,float,float);  
  19.     void display();  
  20. private:  
  21.     float pay;  
  22. };  
  23.   
  24.   
  25. #endif  

  1. //  
  2. //  Graduate.cpp  
  3. //  Programs  
  4. //  
  5. //  Created by bo yang on 4/17/12.  
  6. //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #include <iostream>  
  10. #include "Graduate.h"  
  11. #include "Student.h"  
  12. using namespace std;  
  13.   
  14. void Graduate::display()  
  15. {  
  16.     cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<endl;  
  17.       
  18. }  
  19.   
  20. Graduate::Graduate(int n,string nam,float s,float p):Student(n,nam,s),pay(p)  
  21. {  
  22.       
  23. }  

 

 

  1. //  
  2. //  main.cpp  
  3. //  Student&Graduate  
  4. //  
  5. //  Created by bo yang on 4/17/12.  
  6. //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #include <iostream>  
  10. #include "Student.h"  
  11. #include "Graduate.h"  
  12. using namespace std;  
  13.   
  14. int main(int argc, const char * argv[])  
  15. {  
  16.   
  17.     Student s1(1000,"David",100);  
  18.     Graduate g1(2000,"Jarry",50,20);  
  19.       
  20.     Student *p=&s1;  
  21.     p->display();  
  22.       
  23.     p=&g1;  
  24.     p->display();  
  25.     return 0;  
  26.    }  


 


说明:定义一个Student类,让Graduate类继承Student类后,两个类中共同定义了一个display()方法,因为是在基类和派生类中分别定义的同名同参类,所以没有冲突,但是在调用的时候就出现了问题。我们在主函数中定义一个指针p指向父类对象的首地址,然后用指针p调用display()函数,没问题,我们可以打印出我们想要的数据。然后用指针p指向派生类Graduate的对象首地址,再次调用display()方法,你会发现Graduate中继承父类的成员对象没有被重写,还是父类中成员值,Graduate自己的成员打印了出来是没有问题的,在此说明通过一个指针指向不同的类分别调用不同层次中的同名同参类是不行的。这就需要用到虚函数来解决此问题了。

我们在上述程序中作一点修改:在Student类中声明display()时,加一个关键字virtual即

virtual void display();

这样就把Student类display()声明成一个虚函数。这样就可以实现刚才想要的效果了。

说明:基类指针本来是用来指向基类对象的,如果用它指向派生类对象,则进行指针类型转换,将派生类对象的指针先转换为基类的指针,所以基类的指针指向的是派生类对象中的基类部分

程序修改前,是无法通过基类指针去调用派生类对象中的成员函数的。虚函数突破这一限制,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。只有用virtual声明了虚函数后才具有以上作用。如果不声明为虚函数,企图通过基类指针调用派生类的非虚函数是不行的。

把基类的某个成员函数声明为虚函数后,允许在其派生类中对该函数重新定义,赋予它新的功能,并且可以通过指向基类的指针指向同一类族中不同类的对象,从而调用其中的同名函数。由虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应。

虚函数的使用方法:

1、                    在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,方便使用。

2、                    在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。

3、                    在主函数中定义一个基类指针指向基类对象,引用基类函数;指向派生类对象,引用派生类函数。

C++规定:一个成员函数被声明为虚函数时,派生类中的同名函数都自动成为虚函数。所以派生类中同名函数加不加virtual都是可以的,习惯上添加,程序易懂。

注意:如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。

通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同类的同名函数,只要先用基类指针指向即可。如果指针不断地指向同一类族中的不同类的对象,就能不断调用不同类的对象中的同名函数。

    如果在基类中定义的非虚函数在派生类中被重新定义,如果用基类指针调用该成员函数,系统会调用对象中基类部分的成员函数;如果用派生类的指针调用该成员函数,则系统对调用派生类对象中的成员函数,这不是多态,是不同类型的指针,没有用到虚函数


分享到:
评论

相关推荐

    C++实验六 多态性和虚函数的应用 课程 实验报告

    在C++编程语言中,多态性和虚函数是面向对象编程的重要特性,它们允许程序员创建灵活且可扩展的代码结构。本次实验旨在深入理解和熟练运用这两个概念。实验报告的标题和描述表明,这是一个关于C++实验,特别是针对多...

    c++多态性与虚函数练习题

    在C++中,多态性主要通过虚函数来实现。 #### 二、虚函数的作用及其使用方法 虚函数是一种特殊的成员函数,它可以在派生类中被重写。当通过基类的指针或引用调用一个虚函数时,会自动调用相应派生类的版本。这样就...

    c++课件 多态性与虚函数

    c++课件 多态性与虚函数

    C++实验之多态性和虚函数

    多态性和虚函数

    C++实验报告多态性.doc

    实验中涉及的纯虚函数和虚函数的应用就是动态多态性的体现。 二、实验内容详解 1. `Point`类的构建:包含两个`double`类型的成员变量`x`和`y`,分别表示点的横坐标和纵坐标。提供了默认构造函数初始化为原点(0.0,...

    C++中多态性的演示

    通过这个示例,我们可以看到,C++语言通过虚函数实现了多态性,使得程序更加灵活和可扩展。 Faster。 多态性是面向对象编程的核心概念之一,它使得程序可以根据对象的类型或类别而具有不同的行为。C++语言通过函数...

    c++多态性和虚函数

    ### C++中的多态性和虚函数 在C++编程语言中,多态性是一种重要的特性,它允许子类对象可以被当作其父类对象来处理,从而极大地提高了代码的灵活性和可扩展性。多态性的实现主要依赖于虚函数机制。下面我们将详细...

    C++多态性与虚函数

    第9章 多态性与虚函数 本章学习要求: 虚函数 多态性 静态与动态联编 9.1 多态性的概念 9.2 虚函数 9.3 静态绑定与动态绑定 9.4 纯虚函数和抽象类

    C++中的多态性:深入理解与实践指南

    本文将详细探讨C++中的多态性,包括它的基本概念、实现方式以及如何在实际编程中应用。 多态性是C++中一个强大的特性,它提供了编写灵活、可扩展代码的能力。通过虚函数、函数重载、运算符重载和模板,C++支持多种多...

    C++虚函数表测试源码

    在C++编程语言中,虚函数表(Virtual Function Table,简称vtable)是实现多态性的一个关键机制。本文将深入探讨C++虚函数表的相关知识点,并通过标题中提到的测试源码进行详细讲解。 首先,理解虚函数的定义:在...

    C++虚函数实现原理

    ### C++虚函数实现原理 #### 一、引言 在C++中,虚函数机制是面向对象编程中实现多态的重要方式之一。...对于复杂的继承关系,虚函数表能够有效地管理不同类之间的虚函数调用,从而确保多态性的正确实现。

    C++谭浩强中多态性和虚函数章节中最后的代码

    在C++编程语言中,多态性和虚函数是面向对象编程的重要特性,它们极大地增强了代码的灵活性和可扩展性。本文将深入探讨这两个概念,并基于标题和描述中的提示,解析相关代码实例。 首先,让我们理解多态性。多态性...

    C++ 虚函数表解析

    ### C++虚函数表解析深度剖析 在C++编程语言中,虚函数是实现多态性的关键机制之一,尤其在...通过本文的深入解析,希望能帮助读者更加深刻地理解C++虚函数表的工作原理,为进一步探索和应用多态性打下坚实的基础。

    C++程序设计基础PPT课件8-虚函数与多态性

    《C++程序设计基础》课程中的“虚函数与多态性”是面向对象编程的核心概念之一,主要讨论了如何在C++中实现不同类型的对象共享相同接口的能力,即多态性。多态性使得程序更加灵活,代码复用性更强。在C++中,多态性...

    c++虚函数与虚函数表

    通过对虚函数和虚函数表的理解,我们可以更好地掌握C++中多态性的实现机制。虚函数表是C++中实现多态的关键,它允许我们编写更加灵活和可扩展的代码。同时,理解虚函数表的工作原理也有助于优化程序性能,避免不必要...

    实验4 多态性的应用.doc

    在C++中,多态性可以通过虚函数来实现。虚函数是一种特殊的函数,它可以被子类继承和重写。通过使用虚函数,我们可以在基类中定义一个函数,然后在子类中重写该函数,以便实现不同的功能。 实验目的: 本实验的目的...

    C++多态性实验报告

    本实验报告主要围绕C++中的多态性展开,涉及到构造函数、析构函数、虚函数以及抽象类和纯虚函数的应用。 首先,实验中提到将构造函数修改为带参数的形式,这是为了在创建对象时能直接初始化对象的属性。例如,对于`...

Global site tag (gtag.js) - Google Analytics