请问高手,C++虚函数表是什么?怎么用啊?
楼上说的不全吧,只有纯虚类才无法实例化。
至于不能为虚函数,我的理解是:
构造函数是给类初始化调用的,明白点说就是给类中的成员变量赋初始值。
如果构造函数是虚函数,意味着肯能被重载,也就是在子类实例化的时候给父类初始化时是调用子类重载的函数,先不管合不合法,要想初始化父类,就需呀知道父类的成员变量或函数,这样岂不是父类向子类完全暴露了自己的成员?这不合乎数据封装的概念吧。
当然,这只是我个人理解,当然ANSI最新的标准貌似构造函数是可以为虚的,不过对于现在我来看的话,感觉没什么意思。
C++中虚函数的作用:
1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。
同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。
C++中虚函数的用法:
比如你有个游戏,游戏里有个虚基类叫「怪物」,有纯虚函数 「攻击」。然后派生出了三个子类「狼」「蜘蛛」「蟒蛇」,都实现了自己不同的「攻击」函数,比如狼是咬人,蜘蛛是吐丝,蟒蛇把你缠起来。
然后出现好多怪物的时候就可以定义一个 虚基类指针数组,把各种怪物的指针给它,然后迭代循环的时候直接 monster[i]->attack() 攻击玩家就行了,大概见下图:
扩展资料:
使用虚函数的注意事项:
一、包含虚函数的类指针列表会增大。
二、虚析构函数
析构函数的作用是在对象撤销之前做必要的“清理现场”的工作。当派生类的对象从内存中撤销的时候,会先先调用派生类的析构函数然后再调用基类的析构函数。
当我们new一个临时对象时,若基类中包含析构函数,并且定义了一个指向该基类的指针变量。
三、构造函数不能声明为虚函数
构造函数不能声明为虚函数。如果声明为虚函数,编译器会自动报出。
四、不在析构或者构造过程中调用虚函数
在析构函数或者是构造函数中,我们绝对不能调用虚函数。即使,我们在构造函数或者析构函数中调用虚函数,也不会下降至派生类中调用函数。
虚函数的定义
虚函数用来表现基类和派生类的成员函数之间的一种关系.
虚函数的定义在基类中进行,在需要定义为虚函数的成员函数的声明前冠以关键字 virtual.
基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义.
在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同.
虚函数是重载的一种表现形式,是一种动态的重载方式.
2. 为什么使用虚函数
#include
class CBase{
public:
void who( )
{cout<<"this is the base class!
";}
};
class CDerive1 : public CBase{
public:
void who( )
{cout<<"this is the derive1 class!
";}
};
class CDerive2 : public CBase{
public:
void who( )
{cout< who( );
p = &obj2;
p -> who( );
p = &obj3;
p -> who( );
obj2.who( );
obj3.who( );
return 1;
}
运行结果:
this is the base class!
this is the base class!
this is the base class!
this is the derive1 class!
this is the derive2 class!
通过对象指针进行的普通成员函数调用,仅仅与指针的类型有关,而与此刻正指向什么对象无关.要想实现当指针指向不同对象时执行不同的操作,就必须将基类相应中的成员函数定义为虚函数.
3. 虚函数与重载函数的关系
一般的重载函数,函数的返回类型及所带的参数必须至少有一样不完全相同,只需函数名相同即可.
基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同.
重载虚函数时,若与基类中的函数原型出现不同,系统将根据不同情况分别处理:
(1)仅仅返回类型不同,其余相同,系统会当作出错处理;
(2)函数原型不同,仅仅函数名相同,系统会认为是一般的函数重载,将丢失虚特性.
3.3.4 虚基类
#include
class x{
protected:
int a;
public:
void f ( ) ;
};
class x1 : public x {
public:
x1( ){cout<};
class x2 : public x {
public:
x2( ){ cout<};
class y : public x1, public x2{
public:
y( ){ cout<};
main( )
{
y obj; //error
obj . f ( ) ; //error
return ;
}
二义性错误
非虚基类的类层次
虚基类的类层次
当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类.
class x1 : virtual public x
{
// … …
};
class x2 : virtual public x
{
// … …
};
虚基类的初始化
虚基类的初始化与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同.
派生类构造函数的调用次序有三个原则:
(1) 虚基类的构造函数在非虚基类之前调用;
(2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用;
(3) 若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数.
纯虚函数
仅仅用来为要从基类中派生的函数占据一个位置。
纯虚函数在基类中没有定义,它们被初始化为0。
任何用纯虚函数派生的类,都要自己提供该函数的具体实现。
定义纯虚函数
virtual void myMethod(void) = 0;
By 风之风信子
C++取虚函数地址的问题
class C:public A { public :void CALL output(){ printf("Class Cn");} CALL ~C(){printf("~C()");} };int main(int argc, char* argv[]){ typedef void (CALL *pfun)();A* pa = new B;pfun p = (pfun)*(long*)*((long*)pa);p();delete pa;return 0;} PS: 百度...
在C++中,能否声明虚构函数?为什么?能否声明虚析构函数?为什么?_百度...
原因如下:在C++-中不能声明虚构造函数,多态是不同的对象对同一消息有不同的行为特性,虚函数作为运行过程中多态的基础,主要是针对对象的,面构造函数是在对盘产生之前运行的,因此虚构造函数是没有童义的。在C++中可以声明虚析构函数,析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,如...
...基表,虚基表有神马作用?里面放了那些信息?望高手多多指教...
虚函数表对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。 在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了 这个实例的...
c语言高手们帮忙
函数调用的时候,实参和形参的类型应该匹配,但如果不匹配以赋值转换规则进行类型转换为准.例如若FLOAT型实参值A为3.5,而形参X为INT型,则将实数3.5转换成整数3,然后送到形参B.但此时应将被调函数的前面或在调用前对被调用函数应作函数声明.函数声明格式如下:(函数变量名)(实参表)函数调用...
新手关于C语言中类(Classes)的问题,求高手!
include<iostream> using namespace std;class X { int x; \/\/定义类X的私有实例成员变量x public:X() {x=0;} \/\/默认构造函数(无参数),将x初始化为0 X(int xx) {x=xx;} \/\/重载的构造函数,将x初始化为xx \/\/虚函数,输出x的值,子类可以覆盖(重写)虚函数,从而实现多态 virtual ...
高手替我解释C++中virtual,要详细,谢谢!
多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。多态性是允许将父对象设置成为和一个和多个它的子对象相等的技术,比如Parent:=Child;赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。举个例子...
在c++中,为什么会输出这样的结果呢?看不懂这个程序,请高手帮忙看看
由于基类B定义的fun()是虚函数,所以Iclass继承的fun()同样是虚函数,虚函数的作用是实现多态,虚函数是后绑定原则,即在函数运行中确定地址,而不是在编译的时候确定。对应各自类的地址,由于是虚函数,p1对应Bclass,p2取了obj(即lclass)的地址,p3同p2。
请教关于C++中虚基类的一个问题
C c;c.show();c.show1();return 0;} 报错信息如下:error C2385: 'C::show1' is ambiguous warning C4385: could be the 'show1' in base 'Base' of base 'A' of class 'C'warning C4385: or the 'show1' in base 'Base' of base 'B' of class 'C'改成虚基类就没问题了...
有关虚基类和虚函数
在派生类继承基类时,加上一个virtual关键词则为虚拟基类继承,如: classderive:virtual public base { };虚基类主要解决在多重继承时,基类可能被多次继承,虚基类主要提供一个基类给派生类,如:classB { };classD1:public B { };classD2:public B { };classC:...
请问:虚函数是否和类型兼容规则是否矛盾
对于你上面的问题,派生类对象可以作为基类使用这句话没错,但说的是可以做为基类使用,并不是说派生类就成为了基类。A*a=new B;这句话new了一个B对象,这个对象无论怎么都是B对象,只是用了基类A的指针指向了B,由于指针是基类A,所以只支持调用A自己的方法,又由于show是虚函数,所以就算用A的...
缑选千新: 虚函数的定义 虚函数用来表现基类和派生类的成员函数之间的一种关系. 虚函数的定义在基类中进行,在需要定义为虚函数的成员函数的声明前冠以关键字 virtual. 基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中...
明山区18078828939: C++虚函数怎么理解? - ?
缑选千新: C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有“多种形态”,这是一种泛型技术.所谓泛型技术,...
明山区18078828939: VC++中虚函数的作用??有用吗?谢谢高手指点!! - ?
缑选千新: 在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念.因为它充分体现了面向对象思想中的继承和多态性这两大特性,在C++语言里应用极广.比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说,...
明山区18078828939: 介绍一下虚函数?C++?
缑选千新: 虚函数是在基类中定义的,目的是不确定它的派生类的具体行为.例: 定义一个基类:class Animal//动物.它的函数为breathe()//呼吸. 再定义一个类class Fish//鱼 .它的函数也为breathe() 再定义一个类class Sheep //羊.它的函数也为...
明山区18078828939: 请问什么是虚函数?
缑选千新: 呵呵,我来解释一下吧 1. 虚函数就是专门设计用来被子类实现的,所谓的多态性就体现在这里.具体地说,就是,这个虚函数的函数指针通过虚函数表(virtual table)直接指向用来实现它的子类中去. 2. 在c++里面的虚函数用virtual定义,在java中就用abstract定义,但虚函数不强制要求子类实现. 3. 如果强制要求子类实现,在c++中用纯虚函数定义(让函数=0),这样,这个父类就变成纯虚类了(就是不能实例化的意思); 在java中用接口(interface),实现整个接口的“子类”就必须实现这个方法了.
明山区18078828939: 一个关于C++虚函数表的问题(求高手解释) - ?
缑选千新: ——请解释&b+i对应函数的位置,并简单介绍虚函数表.感觉前面问了一个学术问题,后面则是在求做作业... 总觉得如果你看得懂这个代码,应该不会不知道虚函数表这个东西吧...虚函数表是编译器用来实现多态的方法.一般来说,虚函数表是...
明山区18078828939: 在c++中虚函数和多态性是什么意思 - ?
缑选千新: 多态是指使用相同的函数名来访问函数不同的实现方法,即“一种接口,多种方法”,用相同的形式访问一组通用的运算,每个运算可能对应的行为不同.C++支持编译时多态和运行时多态,运算符重载和函数重载就是编译时多态,而派生类和...
明山区18078828939: 在C++中用虚函数的作用是什么?为什么要用到虚函数 - ?
缑选千新: 虚函数提供一类操作的统一命名. 由于类包含的内容比较广,下面还有不同的子类,虽然操作的名称相同,但是对于不同的子类,其具体实现不同.因此,在本类中无法统一表达;但是另一方面,此类操作具有共性,因此使用一个统一的命名.其具体的实现,有各个不同的子类完成.
明山区18078828939: c++中,虚函数的运行机制是什么?
缑选千新: 对于每一个有虚函数的C++类,编译器为其建立一个虚函数表vtbl.虚函数表中保存是虚函数的地址.编译器为有虚函数的C++类添加一个成员变量.该成员变量是一个指针vtpl,在该类实例化时将其指向该类的虚函数表.当虚函数被调用时,首先跟据vtpl找到vtbl,并找到对应的函数地址,然后调用该函数. 更详细的介绍你可以参考《inside C++ object model》.
明山区18078828939: C问题我初学C++请问纯虚函数到底是什么东西? ?
缑选千新: 不能直接引用,要进行重载. 相当于提供一个公共代码.供类似的函数重载,以免代码冗于.