专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅
-10-26 23:33 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项指向一个虚函数的地址,实现上是一个函数指针的数组。 虚函数表既有继承性又有多态性。每个派生类的vtbl继承了它各个基类的vtbl,如果基类vtbl中包含某一项,则其派生类的vtbl中也将包含同样的一项,但是两项的值可能不同。如果派生类重载(override)了该项对应的虚函数,则派生类vtbl的该项指向重载后的虚函数,没有重载的话,则沿用基类的值。 在类对象的内存布局中,首先是该类的vtbl指针,然后才是对象数据。在通过对象指针调用一个虚函数时,编译器生成的代码将先获取对象类的vtbl指针,然后调用vtbl中对应 [阅读全文] [PDF]
在C++的子类中,定义某成员函数时,我们通常需要显式的调用其基类的版本。例如在一个绘图类结构中,子类只需要去绘制在子类添加进去的部分图形,然后再调用基类去完成基础的图形。这个成员函数有一般都是虚函数。对于构造函数,在子类的构造函数中也可能显式地执行基类的构造函数。 先看看一个例子,基类Shape的默认构造函数不分配name空间,但子类Line的默认构造函数会按照规则自动产生name,这里我们假设name是private的,如果name不是private,问题会很简单,也不会出现下述问题了。但在现实中,通常在基类的构造函数会初使化一些重要的private成员 [阅读全文] [PDF]
假定一组形状类(如Circle、Triangle、Rectangle和Square等等)都是从基类Shape派生出来的。在面向对象的程序设计中,我们可能要使每一个这样的类都能够绘制其自身形状。尽管每个类都有它自己的draw函数,但是绘制每种形状的draw函数却是大不相同的。当需要绘制形状时,不管它是什么形状,把它作为基类Shape的对象处理是再好不过了。然后,我们只需要简单地调用基类Shape的函数draw,并让程序动态地确定(即在执行时确定)使用哪个派生类的draw函数。 为了使这种行为可行,我们把基类中的函数draw声明为虚函数。然后在每个派生类中重新 [阅读全文] [PDF]
如果基类声明了一个函数是虚函数,而且派生类并没有改变参数,只是把函数内容改变了,那么这个可以认为是“重写“ 派生类重载是什么呢,就是在派生类中仅仅保留基类的函数名,参数变了,或者返回类型也变了,如果不改变参数仅仅改变返回类型不是重载,这样也是错的。 如果重载了,你就不会得到基类对应的函数名的函数了,被隐藏了! 除非你使用基类作用域解析符号,要不你调用基类版本就是错误的! 看例子: class C0 { public: virtual void Set1(int i) { cout <<\"C0:Set1 i=\" <<i <& [阅读全文] [PDF]
C++中,以类、虚函数等为代表的数据抽象功能一直是C++的核心和难点。我认为C++的抽象应该是指:从我们需要解决的问题出发,在与该问题相关的一组关联对象中提取出主要的或共有的部分――说简单一点,就是用相同的行为来操作不同的对象。 从提出问题到找出与该问题相关的对象,这是一个互动的、反复的过程。在对相关对象的抽象中,随着认识的深入,我们可能会修改最初的目标,而最初目标的修改又可能使一组新的相关对象被加入进来。如:假设现在要设计一个基于广域网的邮件服务器,首先可能需要通过socket对底层协议进行封装,为高层的pop3、smtp协议提供一组标准的接口。开始为了 [阅读全文] [PDF]
以下代码没有什么实用价值,最多拿来加深一下对虚函数表的印象,一时性起,想直接操纵虚函数表。这段代码只尝试了在VS2005上编译通过,没有在其他编译器上尝试,它并不具有可移植性。 大家都知道C++的虚函数机制通常是通过一个虚函数表来实现的,C++不对内存访问做限制,所以我们可以通过指针自己访问虚函数表,然后进行操作。 #include<iostream> usingnamespacestd; classB { public: virtualvoidfun1() { cout<<\"B::fun1\"<<end [阅读全文] [PDF]
学习 C++ 的同志不知道有没有和我一样遇到过这样的困惑:C++中的虚函数到底怎么实现的?在各种继承关系中,虚函数表的结构到底是什么样的?曾经我是很想当然,可是后来在使用ATL的过程中,我发现并不是我想的那样。大家知道,利用C++语言本身的特性进行COM编程当然是很方便的事,但是你就得随时随地都知道那虚函数表里头到底是些什么东西。讲C++语法的书没有义务告诉你C++产生的虚函数表是什么样的,这就是头痛的所在。 自已做试验是件很快乐的事,我很愿意这么做。 首先写个函数,作为我们实验的基础。传入虚函数表指针,显示虚数表的内容。 void DispVFT [阅读全文] [PDF]
一,什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。下面来看一段简单的代码class A{public:void print(){ cout<<”This is A”<<endl;}};class B:public A{public:void print(){ cout [阅读全文] [PDF]
首先来说一说虚函数,所谓虚函数是这样一个概念:基类中有这么一些函数,这些函数允许在派生类中其实现可以和基类的不一样。在C++中用关键字virtual来表示一个函数是虚函数。 C++中还有一个术语“覆盖”与虚函数关系密切。所谓覆盖就是说,派生类中的一个函数的声明,与基类中某一个函数的声明一模一样,包括返回值,函数名,参数个数,参数类型,参数次序都不能有差异。(注1)说覆盖和虚函数关系密切的原因有两个:一个原因是,只有覆盖基类的虚函数才是安全的。第二个原因是,要想实现基于虚函数的多态就必须在派生类中覆盖基类的虚函数。 接下来让我们说一说为什么要有虚函数,分析一下为什么派 [阅读全文] [PDF]
对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、重载的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。 这里我们着重看一下这张虚函数表。在C++的标准规格说明书中说到,编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置(这是 [阅读全文] [PDF]
1 共10条 分1页