zoukankan      html  css  js  c++  java
  • C++关键字之virtual

    from://http://blog.csdn.net/xuyuanfan/article/details/9935533

    在C++中是没有接口的,要真正实现java中的interface功能,需要使用virtual函数的多态继承机制。这里就细讲一下C++中的virtual关键字的用法。

    首先设计3个类,包括book、good_book和bad_book。book为基类,而good_book和bad_book继承于book类。

    1、book类:包括一个成员变量name和一个虚成员函数getName

    2、good_book类:只有一个成员函数getName

    3、bad_book类:只有一个成员函数getName

    其中book、good_book和bad_book这3个类的getName是同名同参数列表同返回值的成员函数。

    三个类的UML图如下:

    三个类的源代码如下:

    book类的头文件:book.h

    1. #ifndef _BOOK_H_  
    2. #define _BOOK_H_  
    3.   
    4. #include <string>  
    5.   
    6. using namespace std;  
    7.   
    8. class  book{  
    9. protected:  
    10.        string name;  
    11. public:  
    12.        book();  
    13.        virtual string getName();  
    14. };  
    15.   
    16. #endif  

    book类的源文件:book.cpp

    1. #include "book.h"  
    2.   
    3. book::book()  
    4. {  
    5. name = "book";  
    6. }  
    7.   
    8. string book::getName(){  
    9. return name;  
    10. }  

    good_book类的头文件:good_book.h

    1. #ifndef _GOOD_BOOK_H_  
    2. #define _GOOD_BOOK_H_  
    3.   
    4. #include "book.h"  
    5.   
    6. using namespace std;  
    7.   
    8. class good_book : public book{  
    9. public:  
    10.       string getName();   
    11. };  
    12. #endif  

    good_book类的源文件:good_book.cpp

    1. #include "good_book.h"  
    2.   
    3. string good_book::getName(){  
    4. return "good "+name;  
    5. }  

    bad_book类的头文件:bad_book.h

    1. #ifndef _BAD_BOOK_H_  
    2. #define _BAD_BOOK_H_  
    3.   
    4. #include "book.h"  
    5.   
    6. using namespace std;  
    7.   
    8. class bad_book : public book{  
    9. public:  
    10.       string getName();   
    11. };  
    12. #endif  

    bad_book类的源文件:bad_book.cpp

    1. #include "bad_book.h"  
    2.   
    3. string bad_book::getName(){  
    4. return "bad "+name;  
    5. }  

    三个类都设计好了,那现在设计场景(main函数)来运用这三个类,源代码如下:

    场景文件:main.cpp

    1. #include <iostream>  
    2. #include <string>  
    3. #include "book.h"  
    4. #include "good_book.h"  
    5. #include "bad_book.h"  
    6.   
    7. using namespace std;  
    8.   
    9. int main()  
    10. {  
    11.     int pause;  
    12.     cout<<"=================================================================="<<endl;  
    13.     cout<<"使用指向基类的指针bk(指向基类对象book)"<<endl;  
    14.     book *bk;  
    15.     bk = new book();  
    16.     cout<<bk->getName()<<endl;  
    17.     delete(bk);  
    18.       
    19.     cout<<"使用指向基类的指针bk(指向派生类对象good_book)"<<endl;  
    20.     bk = new good_book();  
    21.     cout<<bk->getName()<<endl;  
    22.     delete(bk);  
    23.       
    24.     cout<<"使用指向基类的指针bk(指向派生类对象bad_book)"<<endl;  
    25.     bk = new bad_book();  
    26.     cout<<bk->getName()<<endl;  
    27.     delete(bk);  
    28.     cout<<"=================================================================="<<endl;  
    29.     cout<<"使用指向派生类的指针bks(指向基类对象book)"<<endl;  
    30.     cout<<"不可以"<<endl;    
    31.     //    good_book *bks;  
    32.     //    bks = new book();  
    33.     //    cout<<bk->getName()<<endl;  
    34.     //    delete(bk);  
    35.       
    36.     cout<<"使用指向派生类的指针bks(指向派生类对象good_book)"<<endl;  
    37.     good_book *bks;  
    38.     bks = new good_book();  
    39.     cout<<bk->getName()<<endl;  
    40.     delete(bk);  
    41.   
    42.     cout<<"使用指向派生类的指针bks(指向基类的其他派生类对象bad_book)"<<endl;  
    43.     cout<<"不可以"<<endl;   
    44.     //    good_book *bks;      
    45.     //    bks = new bad_book();  
    46.     //    cout<<bk->getName()<<endl;  
    47.     //    delete(bk);  
    48.     cout<<"=================================================================="<<endl;  
    49.     cout<<"使用基类实例对象Obk"<<endl;   
    50.     book Obk;  
    51.     cout<<Obk.getName()<<endl;  
    52.       
    53.     cout<<"使用派生类实例对象Ogood_book"<<endl;   
    54.     good_book Ogood_book;  
    55.     cout<<Ogood_book.getName()<<endl;  
    56.       
    57.     cout<<"使用派生类实例对象Obad_book"<<endl;   
    58.     bad_book Obad_book;  
    59.     cout<<Obad_book.getName()<<endl;  
    60.       
    61.     cin>>pause;  
    62.     return 0;  
    63. }  


    编译运行程序,得出结果:

    由输出结果可以知道,在两个派生类继承并覆写了基类的虚函数的情况下:

    1、使用基类类型指针,那它指向哪个对象实例就会调用哪个对象的函数;

    2、使用派生类类型指针,它不能指向基类和该基类的其他派生类,只能指向该派生类对象并调用该派生类对象的函数;

    3、使用对象实例,那使用的是哪个对象实例就会调用哪个对象的函数。

    在这里,再把该虚函数改为普通函数,即把book.h 文件的getName函数前面的virtual关键字给去掉,源代码如下:

    book类的头文件:book.h

    1. #ifndef _BOOK_H_  
    2. #define _BOOK_H_  
    3.   
    4. #include <string>  
    5.   
    6. using namespace std;  
    7.   
    8. class  book{  
    9. protected:  
    10.        string name;  
    11. public:  
    12.        book();  
    13.        string getName();  
    14. };  
    15.   
    16. #endif  


    再次编译运行程序,得出结果:

    对照没去掉virtual关键字运行的结果可知道,唯一的区别就是——若使用基类类型指针,那不管它指向哪个对象实例都会调用基类对象的函数;

  • 相关阅读:
    全国省市县三级数据库
    多源教学数据管理系统之团队课设博客
    1.判断字符串中的字符是否Unique
    [转载]linux防火墙基础和管理设置iptables规则
    (转)Sed使用详解
    2.判断回文(Anagrams)
    【转载】关于23 种设计模式的有趣见解
    macbook M1芯片在centos8下安装k8s笔记
    Winform 学习初级 从WebForm到WinForm
    如何建立数据模型
  • 原文地址:https://www.cnblogs.com/wanqieddy/p/3313989.html
Copyright © 2011-2022 走看看