我们为什么要在C++中使用虚函数
类中的成员函数分为静态成员函数和非静态成员函数,而非静态成员函数又分为普通函数和虚函数。
至于为什么虚函数必须是非静态成员函数,可以看一下: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++中使用虚函数的更多相关文章
- EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- C++ 构造函数中调用虚函数
我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...
- C++中的虚函数解析[The explanation for virtual function of CPlusPlus]
1.什么是虚函数? ...
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- C#中的虚函数及继承关系
转载:http://blog.csdn.net/suncherrydream/article/details/8423991 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法. 虚 ...
- C++进阶--构造函数和析构函数中的虚函数
//############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- 【C++】C++中的虚函数与纯虚函数
C++中的虚函数 先来看一下实际的场景,就很容易明白为什么要引入虚函数的概念.假设我们有一个基类Base,Base中有一个方法eat:有一个派生类Derived从基类继承来,并且覆盖(Override ...
随机推荐
- Log4j_学习_03_自己动手封装log工具
二.参考资料 1.log4j 是否可以通过条件判断 在程序运行中动态选择日志存储目录 2.log4j删除N天前日志实现
- Spring Boot 简单日志配置
在生产环境中,只打印error级别的错误,在测试环境中,可以调成debugapplication.properties文件## 默认使用logback logging.level.root=error ...
- linux shell 学习笔记--内部命令学习
.基本命令 新手必须要掌握的初级命令 ls 基本的列出所有文件的命令.但是往往就是因为这个命令太简单,所以我们总是低估它.比如 ,用 -R 选项,这是递归选项,ls 将会以目录树的形式列出所有文件, ...
- HDU - 5977 Garden of Eden (树形dp+容斥)
题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...
- Windows之IOCP
IOCP全称I/O Completion Port,中文译为I/O完成端口.IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的Epoll,关 ...
- ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)
http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...
- Linux下全局安装composer方法
1.下载composer curl -sS https://getcomposer.org/installer | php 2.将composer.phar文件移动到bin目录以便全局使用compos ...
- python 中zip函数的使用
1.ta = [1,2,3] tb = [9,8,7] tc = ['a','b','c'] for (a,b,c) in zip(ta,tb,tc): print(a,b,c) 2. ta = [1 ...
- hexo博客相关
https://www.cnblogs.com/sulishibaobei/p/6428241.html 利用hexo+github+nodejs搭建自我博客的一天 http://www.sulish ...
- Python函数-delattr()
delattr(object, name) 作用: 删除object对象名为name的属性. 参数object:对象. 参数name:属性名称字符串. >>> class Perso ...