首页 技术 正文
技术 2022年11月6日
0 收藏 498 点赞 779 浏览 3051 个字

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图如下:

C++关键字之virtual

三个类的源代码如下:

book类的头文件:book.h

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

book类的源文件:book.cpp

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

good_book类的头文件:good_book.h

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

good_book类的源文件:good_book.cpp

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

bad_book类的头文件:bad_book.h

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

bad_book类的源文件:bad_book.cpp

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

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

场景文件:main.cpp

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

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

C++关键字之virtual

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

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

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

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

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

book类的头文件:book.h

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

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

C++关键字之virtual

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,082
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,556
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,405
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,179
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,815
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898