[C++]详细解释虚函数到底是什么, 有啥用

您所在的位置:网站首页 虚虚的虚是什么意思 [C++]详细解释虚函数到底是什么, 有啥用

[C++]详细解释虚函数到底是什么, 有啥用

2023-08-24 20:13| 来源: 网络整理| 查看: 265

本篇主要试图解释这些疑问: 虚函数是什么, 为什么要用, 有什么好处?

侯捷老师讲虚函数视频(需要能访问油管)

理解虚函数 在语法上, 成员函数之前加virtual关键字就让这个函数变成虚函数函数的继承不应该从内存角度理解, 而是继承调用权(子类可以调用父类函数), OOP的继承特性需要搭配虚函数才能最大化体现继承的优势.成员函数从这个角度可以分成三种: a. non-virtual(非虚函数,普通函数) b. virtual(虚函数), 希望子类重新定义(override), 且自己对它有默认定义 c. pure virutal(纯虚函数), 希望子类一定要重新定义, 且自己对它没有默认定义(其实可以有), 后面加const = 0; virual void draw() const = 0;

为什么要把某些函数设成虚函数? 父类在定义函数时决定暂缓具体实现步骤, 因为子类在设计时有更具体的,精细的想法, 我作为父类的设计者允许子类去override, 通过把自己的函数设置成虚函数, 子类才有机会(权限)去重新定义.

经典例子: 使用word/excel/ppt 软件打开文件时, 先弹出文件浏览框,选好文件之后点OK, 程序是这么处理的: a. 检查文件名称 b. 查找文件是否存在 c. 打开文件 d. 读出来

这一系列步骤给任何设计师写都差不多, 能不能有人把它写好呢, 因为除了最后一步(读文件), 其他步骤都是一样的, 完全可以事先写好. 于是就有人去写了这个公共的部分, 父类叫CDocument, 里面有个OnFileOpen函数 在这里插入图片描述

//Application Framework class CDocument { public: void OnFileOpen() { ... Serialize(); ... } virtual void Serialize() {}; };

父类CDocument的设计者需要写打开文件这个函数时, 因为不知道使用者具体打开哪一种文件(可能是excel, word, ppt等), 就把这个需要具体细节的部分写成一个函数-Serialize, 并把它定义成虚函数, 然后内容空着. 之后, 我们要为word写程序时, 就在word类里把Serialize这个函数补全,

class CMyDoc: public CDocument { virtual void Serialize() {...} };

用的时候实例化子类的object, 调用父类OnFileOpen()方法(OOP里非常常见). 然后在里面遇到了Serialize这个虚函数, 调用了自己实现的Serialize方法.

main() { CMyDoc myDoc; ... myDoc.OnFileOpen(); }

整个调用顺序遵循下图箭头. 在这里插入图片描述 在设计父类的函数(方法)时, 设计了一些动作, 把其中的一个关键部分延缓, 延缓到子类去决定, 我们就把这个函数的做法叫做Template Method(23个Design Pattern 之一). 这个实现一般动作的设计就叫框架(framework), 其中用到了大量Template Method.

有个关键细节问题: 在运行父类里的OnFileOpen时调用了Serialize, 程序是怎么知道要去CMyDoc里去找这个子类的Serialize方法呢? 其实object调用父类方法时:

myDoc.OnFileOpen(); //在编译器眼中长这样 CDocument::OnFileOpen(&myDoc);

调用的那个object的地址会传进来, 变成this, this所指的就是这个myDoc对象, 到Serialize()的时候, 编译器是看成这样的:

this->Serialize();

虚函数表和虚函数指针的概念之后再谈.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3