c++中virtual 虚函数
转载:
https://www.cnblogs.com/weiyouqing/p/7544988.html
在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念。
什么是虚函数:
虚函数是指一个类中你希望重载的成员函数 ,当你用一个 基类指针或引用 指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本。 ——摘自MSDN
#include <iostream>
using namespace std; class Parent
{
public: char data[20];
void Function1();
virtual void Function2(); // 这里声明Function2是虚函数 }parent; void Parent::Function1()
{
printf("This is parent,function1\n");
} void Parent::Function2()
{
printf("This is parent,function2\n");
} class Child:public Parent
{
void Function1();
void Function2(); } child; void Child::Function1()
{
printf("This is child,function1\n");
} void Child::Function2() {
printf("This is child,function2\n");
} int main(int argc, char* argv[])
{
Parent *p; // 定义一个基类指针
if(_getch()=='c') // 如果输入一个小写字母c
p=&child; // 指向继承类对象
else
p=&parent; // 否则指向基类对象
p->Function1(); // 这里在编译时会直接给出Parent::Function1()的入口地址。
p->Function2(); // 注意这里,执行的是哪一个Function2?
return 0; }
用任意版本的Visual C++或Borland C++编译并运行,输入一个小写字母c,得到下面的结果:
1 This is parent,function1
2 This is child,function2
为什么会有第一行的结果呢?
因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。 那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就是说,它是一个虚函数。
虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。
如果我们在运行上面的程序时任意输入一个非c的字符,结果如下:
1 This is parent,function1
2 This is parent,function2
请注意看第二行,它的结果出现了变化。程序中仅仅调用了一个Function2()函数,却可以根据用户的输入自动决定到底调用基类中的Function2还是继承类中的Function2,这就是虚函数的作用。
PS:一定要注意“静态联翩 ”和“ 动态联编 ”的区别;对于我来说,若没有在VC6.0中亲自去测试,凭自己的感觉,
当在键盘中输入“c”时,我会觉得由于有p=&child;这一句代码,我会认为结果都是:
1 This is child,function1
2 This is child,function2
但是结果却是:
1 This is parent,function1
2 This is child,function2
因为虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实,它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。
第二行中调用了子类的function2,完全是因为virtual 的功能,virtual实现了动态联编,它可以在运行时判断指针指向的对象,并自动调用相应的函数。
p=&parent; //这一句,该指针很明显的是指向父类,那么肯定调用的是父类的方法
c++中virtual 虚函数的更多相关文章
- C++中的虚函数解析[The explanation for virtual function of CPlusPlus]
1.什么是虚函数? ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- C++ 构造函数中调用虚函数
我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...
- 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 ...
随机推荐
- 驱动IO模型-select
新人学习,欢迎指正 部分select.c代码 应用层 select(maxfd+1,&rfds,NULL,NULL,NULL); -------------------(系统调用)------ ...
- js 之k个一组翻转链表
题目描述 将给出的链表中的节点每\ k k 个一组翻转,返回翻转后的链表如果链表中的节点数不是\ k k 的倍数,将最后剩下的节点保持原样你不能更改节点中的值,只能更改节点本身.要求空间复杂度 \ O ...
- linux停止nginx服务 未成功
在上线新功能的时候,需要将服务器停掉,防止在更新过程中有用户进行操作额外的数据. 1:查看nginx主进程: ps -ef | grep nginx 这里root 后面的数字表示:主进程号nginx后 ...
- python FastAPI 初接触
先吹一波: 原来写接口可以这么简单!!! 简单到没朋友 . 中文官网:https://fastapi.tiangolo.com/zh/tutorial/header-params/ 且天然支持异步处理 ...
- 1.3redis小结--配置php reids拓展
1.执行php文件 输出phpinfo(); <?php phpinfo(); 2.根据PHPinfo的信息确定需要下载的 php_redis.dll , php_igbinary.dll 版 ...
- python列表底层实现原理
Python 列表的数据结构是怎么样的? 书上说的是:列表实现可以是数组和链表.顺序表是怎么回事?顺序表一般是数组. 列表是一个线性的集合,它允许用户在任何位置插入.删除.访问和替换元素.列表实现是基 ...
- 10.9 Rewrite原理
Rewrite Rewrite 通过正则表达式的使用改变URI(相对),可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理 Rewrite 接受到的URI不包含host地址 Rewr ...
- JUC多线程之ThreadPoolExecutor类任务执行流程
ThreadPoolExecutor类: ThreadPoolExecutor是我们最常用的一个线程池类,它实现了AbstractExecutorService接口.首先来看一下它的构造器及相关关键变 ...
- golang []byte和string的高性能转换
golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...
- 洛谷3783 SDOI2017 天才黑客(最短路+虚树+边转点+线段树优化建图)
成功又一次自闭了 怕不是猪国杀之后最自闭的一次 一看到最短路径. 我们就能推测这应该是个最短路题 现在考虑怎么建图 根据题目的意思,我们可以发现,在本题中,边与边之间存在一些转换关系,但是点与点之间并 ...