C++入门之初话多态与虚函数

多态性是面向对象程序设计的又一个重要思想,关于多态的详尽描述,请看本人的收藏https://www.cnblogs.com/hust-ghtao/p/3512461.html。这篇博文中,详尽的探讨了多态的一些特性。

在此,我仅仅以白话的方式描述为何要引入多态:

子类继承了基类的方法,但子类可以改变这些这些方法以适应自己的特性,而不是只能照搬基类的方法。现在面临这样一个问题:访问的便捷性和权限。

我们可以使用对象名的方式来访问方法,或者使用类指针,类引用的方式来访问,这都是完全OK的。关键问题在于,假如我们有很多派生子类,比如1000个,当我们要访问具有类似功能(但又有所差异的)的接口时,难道还要用很多对象名去访问吗?显然不科学,一方面,我们这样做,使得程序缺乏灵活性,易读性,还费时费力。

那么有没有一种方法使得我们能够用一种统一的方式来进行这种访问呢?有的,那就是虚函数。

见一段代码:

 1 # include "iostream"
 2 using namespace std;
 3 class Base
 4 {
 5 public:
 6      void funpublic()
 7     {
 8         cout << "基类的成员函数" << endl;
 9     }
10 };
11
12 class child1 :public Base
13 {
14 public:
15     void funpublic()
16     {
17         cout << "派生类child1的成员函数" << endl;
18     }
19 };
20
21
22 class child2 :public Base
23
24 {
25 public:
26     void funpublic()
27     {
28         cout << "派生类child2的成员函数" << endl;
29     }
30 };
31 int main() {
32     Base * p1, *p2, *p3, base;//假如在基类中不使用虚函数,则当我们定义一个基类指针时,就注定我们所访问的方法就是基类方法,但如果我们想访问派生类方法,就
33                               //没有这个访问权限;但若我们定义派生类指针,则只能够指向某一个派生类,无法指向其他派生类(包括基类)。但程序初衷是:设计一种方式
34                               //这种方式能够访问基类和派生类中方法相同(实现方式有所差异)的接口,能够随着我们所调用的对象的所属类,自动调用相应的方法(如果有)
35                               //这时,就要采用相应的虚函数的方法。
36     child1 obj1;
37     child2 obj2;
38     base = obj1;
39     base.funpublic();
40     Base  &aliasbase = obj2;
41     aliasbase.funpublic();
42     p1 = &obj1;
43     p2 = &obj2;
44     p1->funpublic();
45     p2->funpublic();
46     p2 = new child1;
47     p2->funpublic();
48     p3 = new child2;
49     p3->funpublic();
50     system("pause");
51     return 0;
52 }

上述这段代码中没有使用虚函数,我们看一下结果:

我们本意是试图通过指针去访问子类的方法,但是失败了,原因是:倘若我们偷懒,想只定义一个基类指针,就能完成对所有子类同一方法的访问,但是很明显,基类指针不具备这样的访问权限,也就是,当我们定义一个基类指针时,就注定了我们基类指针所指向的对象的指针(这里应该叫地址)会被转化为基类的地址,也就是,我们没有办法去访问真正意义上的派生类指针,当然,我们定义一个派生类指针,也不能够访问其他派生类的方法,当然,更不能访问基类方法。

那么有没有一种方法,能够帮助我们一劳永逸,只定义一个指针就能访问其他所有派生类同名方法呢?有的

 1 # include "iostream"
 2 using namespace std;
 3 class Base
 4 {
 5 public:
 6      virtual void funpublic()
 7     {
 8         cout << "基类的成员函数" << endl;
 9     }
10 };
11
12 class child1 :public Base
13 {
14 public:
15     void funpublic()
16     {
17         cout << "派生类child1的成员函数" << endl;
18     }
19 };
20
21
22 class child2 :public Base
23
24 {
25 public:
26     void funpublic()
27     {
28         cout << "派生类child2的成员函数" << endl;
29     }
30 };
31 int main() {
32     Base * p1, *p2, *p3, base;//假如在基类中不使用虚函数,则当我们定义一个基类指针时,就注定我们所访问的方法就是基类方法,但如果我们想访问派生类方法,就
33                               //没有这个访问权限;但若我们定义派生类指针,则只能够指向某一个派生类,无法指向其他派生类(包括基类)。但程序初衷是:设计一种方式
34                               //这种方式能够访问基类和派生类中方法相同(实现方式有所差异)的接口,能够随着我们所调用的对象的所属类,自动调用相应的方法(如果有)
35                               //这时,就要采用相应的虚函数的方法。
36     child1 obj1;
37     child2 obj2;
38     base = obj1;
39     base.funpublic();
40     Base  &aliasbase = obj2;
41     aliasbase.funpublic();
42     p1 = &obj1;
43     p2 = &obj2;
44     p1->funpublic();
45     p2->funpublic();
46     p2 = new child1;
47     p2->funpublic();
48     p3 = new child2;
49     p3->funpublic();
50     system("pause");
51     return 0;
52 }

这段代码与前面一段代码仅仅多了一个关键字,但是结果大不相同:

可见,当我们将类方法声明为虚方法的时候,大大提高了基类指针的访问权限,使得基类指针能够真正意义上访问子类方法,因此,使用虚函数的方法实现多态是一种优秀的程序设计理念。

关于虚函数和多态细节信息请见我开篇转载博客。

原文地址:https://www.cnblogs.com/shaonianpi/p/10294347.html

时间: 2024-10-13 07:35:54

C++入门之初话多态与虚函数的相关文章

GeekBand-secondweek-c++的多态和虚函数

多态与虚函数 13章的简单继承只是实现了对已有对象的实现的重定义和直接调用,但是向上映射导致的对象切割仍然是个缺陷: 1.延续13章的向上映射 简单继承中,派生类重定义了基类的成员函数,此时,向上映射的结果是很明显的,它使用了基类实现的函数版本,这显然并不是我们想要的效果:为什么会有这样的结果发生,我们先探讨几个问题: 函数调用绑定:函数调用确定目标函数体称为捆绑,编译期绑定称为早绑定,上面的问题就是早绑定引起的,因为编译器只知道基类对象的类型,调用函数也会绑定基类实现的函数版本,要解决这一问题

C++中的多态与虚函数的内部实现

1.什么是多态 多态性可以简单概括为“一个接口,多种方法”. 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可以用自己的方式去响应共同的消息.所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数.这是一种泛型技术,即用相同的代码实现不同的动作.这体现了面向对象编程的优越性. 多态分为两种: (1)编译时多态:主要通过函数的重载和运算符的重载来实现. (2)运行时多态:主要通过虚函数来实现. 2.几个相关概念 (1)覆盖.重

C++的多态与虚函数

多态性:对于同一消息,不同的对象由不同的响应方式 多态分为静态多态(编译时多态)和动态多态(运行时多态),动态多态通过虚函数来实现. 覆盖-->子类和父类中有同名同参数列表但是功能不同的函数叫做覆盖,在同一个类中有相同的是重复定义,不是覆盖. 虚函数的使用方法,如下: ①在基类中声明一个函数为虚函数,如: //基类vStudent class vStudent { public: vStudent(int,string); virtual void display();//虚函数,用来实现多态性

PKU C++程序设计实习 学习笔记3 多态与虚函数

第六章 多态与虚函数 6.1 多态和虚函数的基本概念 引言 多态是面向对象程序设计里面非常重要的这个机制.它能很有效的提高程序的可扩充性. 有些程序设计语言有被对象继承的概念,但是没有多态的概念,那这样的程序设计语言只能被称作基于对象的程序设计语言,而不能称为面向对象的语言, 比方说visual basic. 虚函数 在类的定义中,前面有 virtual 关键字的成员函数就是虚函数. class base { <span style="color:#ff0000;">vir

多态实现--虚函数与纯虚函数

多态实现--虚函数与纯虚函数 C++中实现多态是使用虚函数表的方法实现的. 那么具体怎么实现的呢? 举例说明 假设有这样一个多态场景: 有一个基类动物(animal类),动物里面又有两个派生类:猫(cat类)和狗(dog类).现在要求动物类有一个共同的方法:叫声(voice成员函数),但猫和狗叫声是不同的(即:它们的叫声实现方法不同). 那么代码怎么写呢? 多态的代码实现 #include <iostream> using namespace std; //1. 定义一个纯虚函数 class

C++中类的多态与虚函数的使用

C++的三大特性:封装.继承.多态.以前学的时候自己没去总结,记得在一本c++入门的书讲得还是比较清楚.今天上网找了一下多态,找到下面这篇文章写得比较清晰. http://pcedu.pconline.com.cn/empolder/gj/c/0503/574706.html 类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的,其实不然,Visual BASIC 6.0 是典型

C++ 多态与虚函数

1.多态的概念 由虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应. 先看下面这个简单的例子: #include<iostream> using std::cout; using std::endl; class A { public: void print(){cout << "I am A's print" << endl;} }; class B : public A { public: void print()

多态与虚函数

无论是在编译还是在运行时,c++都支持多态性.编译时的多态是通过重载函数和运算符实现的,而编译时的多态则是通过使用继承和虚函数实现的. 虚函数:是一个成员函数,该函数在基类声明,在派生类中重新定义.再基类中将成员函数声明前加关键字virtual,当继承包含虚函数的类时,派生类将重新定义虚函数. 虚函数实现了“一个接口,多种方法”.

C++多态和虚函数学习笔记

1.从实现的角度看,多态可以划分为两种情况:编译期多态和运行时多态. 前者是在编译过程中,确定同名操作的具体操作对象,从而确定同名函数的具体实现: 后者是在程序运行过程中,动态确定具体的操作对象,从而确定同名函数的具体实现. 这种确定操作具体对象的过程成为联编或联合.联编就是将一个标识符和一个存储地址联系在一起的过程,是计算机程序自身彼此相关联的过程. 从联编进行的不同阶段,可以将联编分为静态联编和动态联编. (1)静态联编是指联编工作在程序编译和连接阶段完成的联编过程.静态联编是程序编译之前进