类中的成员函数分为静态成员函数和非静态成员函数,而非静态成员函数又分为普通函数和虚函数。

至于为什么虚函数必须是非静态成员函数,可以看一下:http://blog.csdn.net/leiming32/article/details/8619893

我们在类中定义函数的时候,在前面加上virtual就可以声明为虚函数。

接下来我们看一个例子:

#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
Student(string n,string nam,int sco);
virtual void display();
protected:
string num;
string name;
int score;
};
Student::Student(string n,string nam,int sco)
{
num=n;
name=nam;
score=sco;
}
void Student::display()
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"score:"<<score<<endl;
}
class Graduate:public Student
{
public:
Graduate(string n,string nam,int sco,string un);
virtual void display();
private:
string university;
};
Graduate::Graduate(string n,string nam,int sco,string un):Student(n,nam,sco),university(un){};
void Graduate::display()
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"score:"<<score<<endl;
cout<<"university:"<<university<<endl;
}
int main()
{
Student *p;
p=new Student("001","QianShou",100);
p->display();
cout<<"==============没有节操的分割线================"<<endl;
p=new Graduate("001","QianShou",100,"SDNU");
p->display();
return 0;
}

运行结果:

/*
num:001
name:QianShou
score:100
==============没有节操的分割线================
num:001
name:QianShou
score:100
university:SDNU
*/

p是基类指针,当它指向基类的对象时,调用的display函数为基类中的成员函数,当它指向派生类的对象时,调用的display函数为派生类中的成员函数。

这就难免出现一个问题,我们为什么要用指向基类的指针指向派生类,然后再通过指针调用派生类中的成员函数呢?

为什么不直接建立一个指向派生类的指针,然后调用成员函数呢?这样都没有必要在基类中声明虚函数了。

我们考虑这样一个问题,如果我们要去一个城市的好多不同的地方,如果我们乘坐公交车的话,每去一个地方就需要选择不同的公交车;而如果我们乘坐出租车的话,我们只需要找一个出租车,然后不断告诉它不同的地点,它就能够带我们去不同的地方。

道理是相似的:

乘坐公交车:

假如一个基类有20个派生类,当我们分别访问这21个派生类和基类的时候,我们就需要为每一个类建立一个指针,然后通过不同的指针去访问不同的类的对象,就好像我们通过乘坐不同的公交车到达不同的地点一样。

乘坐出租车:

如果我们在基类中建立相应的虚函数,我们就只需要建立一个指向基类的指针。当我们需要访问该基类或者它的20个派生类的时候,我们只需将相应的类的地址赋给指向基类的指针,即可访问该派生类中的虚函数。就像我们在做出租车的时候,不断告诉司机我们的下一个地址一样。

我们为什么要在C++中使用虚函数的更多相关文章

  1. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  2. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  3. C++ 构造函数中调用虚函数

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...

  4. C++中的虚函数解析[The explanation for virtual function of CPlusPlus]

    1.什么是虚函数?                                                                                            ...

  5. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  6. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  7. C#中的虚函数及继承关系

    转载:http://blog.csdn.net/suncherrydream/article/details/8423991 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法. 虚 ...

  8. C++进阶--构造函数和析构函数中的虚函数

    //############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...

  9. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  10. 【C++】C++中的虚函数与纯虚函数

    C++中的虚函数 先来看一下实际的场景,就很容易明白为什么要引入虚函数的概念.假设我们有一个基类Base,Base中有一个方法eat:有一个派生类Derived从基类继承来,并且覆盖(Override ...

随机推荐

  1. HTML代码中的空格和空行

    HTML 代码中的所有连续的空格或空行(换行)都会被显示为一个空格. 例子1:(文本内容中的连续空格) 代码 <p>这段文本中,输入连续的空格 大概输入了十个.</p> 显示效 ...

  2. 打印控件Lodop

    官网:http://www.lodop.net/demo.html Lodop.C-Lodop使用说明及样例   Lodop(标音:劳道谱,俗称:露肚皮)是专业WEB控件,用它既可裁剪输出页面内容,又 ...

  3. php 与 Smarty 中的 isset

    今天在做一个分页模块的时候,在获取前端返回的当前页时,烦了一个大错!本来应该是这样子滴: 而咱却写成了这个样子: 在php里输出测试都没错,结果到Smarty里就被拒了! 测试结果是 这货跟谁都相等, ...

  4. Docker-安装与部署

    本文在CentsOS下安装Docker 1.安装前准备工作 系统要求: 在CentOS下需要64位的CentsOS 7  OS requirements To install Docker, you ...

  5. LeetCode Binary Tree Tilt

    原题链接在这里:https://leetcode.com/problems/binary-tree-tilt/description/ 题目: Given a binary tree, return ...

  6. 在C#中实现截获shell程序的输出

    在Windows环境下的所谓shell程序就是dos命令行程序,比如VC的CL.exe命令行编译器,JDK的javac编译器,启动java程序用的java.exe都是标准的shell程序.截获一个sh ...

  7. keepalived之 Keepalived 原理(定义、VRRP 协议、VRRP 工作机制)

    1.Keepalived 定义 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器 ...

  8. 洛谷【P1714】切蛋糕

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://www.luogu.org/problemnew/show/P1714 ...

  9. poj 3421 X-factor Chains——质因数分解

    题目:http://poj.org/problem?id=3421 记忆化搜索竟然水过去了.仔细一想时间可能有点不对,但还是水过去了. #include<iostream> #includ ...

  10. CF gym 101933 K King's Colors —— 二项式反演

    题目:http://codeforces.com/gym/101933/problem/K 其实每个点的颜色只要和父亲不一样即可: 所以至多 i 种颜色就是 \( i * (i-1)^{n-1} \) ...