C++虚函数的缺陷
MFC中的消息机制没有采用C++中的虚函数机制,原因是消息太多,虚函数内存开销太大。在Qt中也没有采用C++中的虚函数机制,原因与此相同,其实这里还有更深层次上的原因,大体说来,多态的底层实现机制只有两种:
1. 一种是按照名称查表
2. 一种是按照位置查表
两种方式各有利弊,而C++的虚函数机制无条件的采用了后者,导致的问题就是在子类很少覆盖基类函数实现的时候内存开销太大,再加上象界面编程这样子类众多的情况(大概是都不覆盖),基本上C++的虚函数机制就废掉了,于是各家库的编写者就只好自谋生路了,说到底,这确实是C++语言本身的缺陷。
参考:http://blog.csdn.net/oowgsoo/article/details/1529411
----------------------------------------------------------------------------------
感叹一句,还真的是自谋生路啊,而且是不约而同的,Delphi就采用了dynamic机制,以减小子类的内存开销,而且大多数是不必要的虚函数开销。
在这些方法里:
1. VC++使用一组结构体的宏定义来实现消息映射,从而解决虚函数的缺陷。
2. Qt的信号槽机制其实就是按照名称查表。
3. Delphi则通过dynamic机制从编译器的角度来解决这个问题。这些方法里,自然是Delphi的方法最简洁方便,因为没有多余的宏,没有生成的临时代码。
----------------------------------------------------------------------------------
以前一直不明白为什么说Delphi语法优美,现在有2点体会,好像是这么回事:
1. C++的宏定义表面上是个好东西,也确实是个好东西,因为可以做无穷无尽的扩展(QT就是一个典型的例子),但用它就会把源代码搞的很复杂,你完全都不知道编译器/类库会把你的源代码替换成什么东西。VC++也是靠这套方法实现消息机制的,QT更夸张,每个文件都要生成moc文件才能真正进行编译。而Delphi的源代码就是源代码,对所有人/所有库都平等,没有什么隐晦的代码。
2. Delphi的编译器做了很多事情,Delphi的库也提前把许多事情都做好了(比如TPageControl如果要在VC++和QT中实现,使用起来烦不胜烦,谁用谁知道),使之手敲的代码看起来尽可能的少。
C++虚函数的缺陷的更多相关文章
- 看懂下面C++代码才说你理解了C++多态虚函数!
#include <iostream> using namespace std ; class Father { private : virtual void Say() //只有添加 ...
- 虚函数&多态
对于经常被问到的虚函数和多态的问题,发现百度百科回答得十分详细,所以自己在百度百科上的解释进行总结 一.虚函数 (1)虚函数简介:在某基类中声明为virtual并在一个或者多个派生类中被重新定义的成员 ...
- 【黑客免杀攻防】读书笔记14 - 面向对象逆向-虚函数、MFC逆向
虚函数存在是为了克服类型域解决方案的缺陷,以使程序员可以在基类里声明一些能够在各个派生类里重新定义的函数. 1 识别简单的虚函数 代码示例: #include "stdafx.h" ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- 匹夫细说C#:从园友留言到动手实现C#虚函数机制
前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编 ...
- 【C++】多态性(函数重载与虚函数)
多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...
- 虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针. 也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual) #include<iostream> usi ...
- C++ 系列:虚函数
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...
随机推荐
- online training
https://www.skillfeed.com/browse http://teamtreehouse.com/features http://www.pluralsight.com/ https ...
- Daily Scrum3
今天我们小组开会内容分为以下部分: part 1: 汇报之前分配的任务进度: part 2:分配明天的任务. ◆Part 1 组员进度报告 彭佟小组完成的优化目标: 关于软件防滥用及垃圾信息拦 ...
- android 系统应用在运行时被卸载
android 系统应用在运行时被rm 掉了,是否还会运行? 环境:root,且开机运行 经过试验,apk本身是在 /system/app 目录下面,且apk已经运行了,这个时候直接 rm /syst ...
- Grails 1.2参考文档速读(10):Controller
转载:http://keyvalue.blog.51cto.com/1475446/303260 从本篇起,我们将开始进入Grails的Web层,首先让我们从Controller说起. G ...
- maven ArtifactTransferException: Failure to transfer
我在使用Myeclipse碰见这个错误,我没有用伺服,直接连接到maven中心. ArtifactTransferException: Failure to transfer org.apache.h ...
- Understanding Convolution in Deep Learning
Understanding Convolution in Deep Learning Convolution is probably the most important concept in dee ...
- CSL概述(翻译总结自TI官方文档)
一.简单介绍 CSL是函数,宏和符号常数的集合,用来控制和配置片上外设.(Chip Support Library) 每一个外设都有自己对应的CSL模块.每个模块有自己的支持符,来表示对于给定的设备, ...
- UML交互图(转载)
概述: 从名字交互作用很明显,图中是用来描述一些不同的模型中的不同元素之间的相互作用.所以,这种相互作用是动态行为的系统的一部分. 这种互动行为表示UML中的两个图,被称为序列图和协作图.这两个图的基 ...
- 封装dll遇到的奇葩错误:error LNK2005: _DllMain@12 已经在 DLLMain.obj 中定义
在定义一个dll工程的时候,一添加MFC的头文件就会报出这个 错误:error LNK2005: _DllMain@12 已经在 DLLMain.obj 中定义 既蛋疼又蛋疼!! 然后逛论坛,查资料 ...
- ZendStudio导入一个已有的网站
解决方法:新建'PHP Project',选择'Create project at existiong location(from existing source)',路径指向你的网站根目录.