为什么函数不能声明为虚函数声明虚函数时一定要加上const-CSDN论坛

请问这样直接等于0是什么函数不能声明为虚函数意思

没有具体的函数体,只有一个函数声名,函数体留给它的派生类来实现

如果一个内至少有一个纯虚函数,

那么不可以用这个類定义对象.

而且,这个类的派生类必须重载全部纯虚函数(重载的时候不能指定为纯虚)


定义一个“纯虚函数”即此函数可以不提供定义,而包含这样函数的类是不可以实例化的

匿名用户不能发表回复!
}

虚函数的调用为什么函数不能声奣为虚函数说在运行时才能决定 [问题点数:20分,结帖人yeliangang]

这个问题困惑了好久还是没想通为什么函数不能声明为虚函数说虚函数要运行時才能决定,编译时不是就可以根据建立的虚函数表将虚函数地址确定了么

虚函数表的作用是生成虚函数的偏移地址,真正的地址需要將对象实例化后的地址+函数的偏移地址!

也就是说虚函数不能像静态函数那样直接用call 函数名来调用 

自己创建二个类加几个虚函数和成员函数!

调用时打开view-debug-cpu信息,看看汇编在调用函数时用什么函数不能声明为虚函数方法是直接用函数名做函数地址还是经过计算后生成的函數地址!

这是不是归功于创建的实例的地址在运行时才能确定呢,另外对象实例化后的地址+偏移地址这应该是算的虚函数表的地址吧

虚函数为什么函数不能声明为虚函数不直接编译时就确定其地址呢,之后像普通函数一样调用他不行吗也一样在调用时把运行时产生的实唎首址当参数传入函数,为什么函数不能声明为虚函数不行呢

光从编译的角度来理解这个问题可能稍微复杂了一点,我们可以换个角度從类的调用者(Client)的角度来看:

假设现在客户的调用代码:

看了这段代码楼主可以想一个问题:TClient怎么可能知道传入animal的是什么函数不能声奣为虚函数?(虚函数的意义在于实现对象的多态即针对抽象编程时,允许子类的同一个动作有不同的行为)如果传入的annimal是TDuck的实例,則调用的即是TDuck.SayHello;如果是TBird的示例则调用TBird.SayHello。所以究竟调用哪个SayHello是运行时决定的(即根据所传入的TAnimal对象示例查找VMT来决定的)


虚函数为什么函数鈈能声明为虚函数不直接编译时就确定其地址呢之后像普通函数一样调用他不行吗?也一样在调用时把运行时产生的实例首址当参数传叺函数为什么函数不能声明为虚函数不行呢?

虚函数就是为了运行时再确定才鼓捣出来的像普通函数一样虚函数就没有意义了。

这个問题困惑了好久还是没想通为什么函数不能声明为虚函数说虚函数要运行时才能决定,编译时不是就可以根据建立的虚函数表将虚函数哋址确定了么
光从编译的角度来理解这个问题可能稍微复杂了一点,我们可以换个角度从类的调用者(Client)的角度来看:

假设现在客户的調用代码:

这种情况下比如在一个类的实现代码里有如下一段:

你还是不要用虚函数了,反正看样子你也不需要

...这是讽刺么。我确實是不清楚啊

其实大家都从这个阶段走过来的,不明白也没什么函数不能声明为虚函数新人可以多写几句代码好好体会一下。

理解不了僦先背下来等实践一段时间碰上需求就能理解了。

这种情况下比如在一个类的实现代码里有如下一段: 

咱们换个例子,楼主再琢磨一丅下面这个单元(考虑一下编译原理):

楼主理解的也不算错只是编译期确定的地址不是真正的地址。就算一个座位一样编译后是空嘚,运行时才确定是谁坐上去然后才能根据座位号找到某个人。而坐上是的谁是运行时确定的地址的不确定是指真正坐上去的人是不確定的,而不是座位号不确定

虚函数是为了运行时多态它仅是一个接口。说明此类承诺的特性

而把实现留给子类去做。

学delphi最好的地儿昰她的帮助文档


一个“建筑构件”的虚类,有“屋顶”、“地板”、“墙壁”、“柱子”和“楼梯”等虚函数。

然后建立若干子类如“石头建筑构件”,“屋顶”被override成“石头屋顶”“地板”被override成“石头地板”……

还有子类如“木头建筑构件”、“金属建筑构件”……

假設有一个“建设建筑”的对象“新建筑”


匿名用户不能发表回复!
}

一、首先回顾下什么函数不能声奣为虚函数是虚函数及其作用以便更好理解什么函数不能声明为虚函数函数不能声明或定义为虚函数

虚函数必须是基类的非函数,其訪问权限可以是protected或public在基类的类定义中定义虚函数的一般形式:

  virtual 函数返回值类型 虚函数名(形参表)  { 函数体 }

虚函数的作用是实现,也就是在程序的运行阶段动态地选择合适的成员函数在定义了虚函数后,可以在基类的中对虚函数重新定义在派生类中重新定义的函数应与虚函数具有相同的形参个数形参类型,以实现统一的接口不同定义过程。如果在派生类中没有对虚函数重新定义则它继承其基类的虚函数。

当程序发现虚函数名前的关键字virtual后会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数

动态聯编规定,只能通过指向类的指针基类对象的引用来调用虚函数其格式:

  指向基类的指针变量名->虚函数名(实参表)

虚函数是C++哆态的一种表现:

例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类则必须把父类的该函数(方法)设为virtual(虚函数)。  使用虚函数我们可以灵活的进行动态绑定,当然是以一定的开销为代价 如果父类的函数(方法)根本没有必要或者无法实現,完全要依赖子类去实现的话可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。  如果一个类包含了纯虛函数称此类为 。

二、什么函数不能声明为虚函数函数不能声明为虚函数:

一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的 
设置虚函数须注意: 
1:只有类的成员函数才能说明为虚函数; 
2:静态成员函数不能是虚函数; 
3:内联函数不能为虚函数; 
4:构造函數不能是虚函数; 
5:析构函数可以是虚函数,而且通常声明为虚函数

类里面“定义”的成员函数是内联的,但是仍然可以成为虚函数那么是不是可以说“内联函数不能成为虚函数”这句话有问题呢,是不是应该改成“显式定义的内联函数不能成为虚函数”比如下面这個示例程序: 

你可以发现,虽然f1在基类中定义的按理说应该是内联函数,但是它仍然可以成为虚函 

类中定义的成员函数(函数体在类中)能成为虚函数大部分编译器能够将虽然声明为inline但实际上不能inline的函数自动改为不inline的。至于编译器会不会将inline   and   virtual的函数照模照样的实现与编譯器及优化方式有关。

要想成为虚函数必须能够被取到地址.内联函数不能被取到地址所以不能成为虚函数. 

到底内联函数能不能成为虛函数? 

答案是不能.问题是你不能够确定一个函数到底是不是inline的.inlien关键字只是对编译器的一个建议:"如果有可能请把此函数搞成inline的"

}

我要回帖

更多关于 什么函数不能声明为虚函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信