虚函数和普通函数的区别在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对这里是没

来源:学生作业帮助网 编辑:作业帮 时间:2024/11/05 18:44:15
虚函数和普通函数的区别在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对这里是没
xWmOW+(Ru_ǁ4ZuZf6611YiW+ 6/E i /̽3ι3;6Z] s99o93,m.}uN~RKc%ɷH'R/W$[5ao!O ޚ3SWxyifzs9+Uؼ)SzkWiy/{߁yѯWVn.lyXfwb\8%WlThm7fFo.{,{n0;}{0muj<ƽIfѸlbD}*OO?}WXNMG^2:%'SӣEgFթgLjQy g%ANkIR\%_T J E%~ ^/WpL%!E5#>?Fe1ߒ%IXA%dcR@SCScFdX ~&>kDCR<PBbbH R+~)JܧDQ}a%(I25AEwTIC>_ J! Ox]wPIrB{&?5.ڐJ*&'c:EVRKP5v=->4gN< Ђ|eB=#\jF5*Y[kӓ٧gG4vFz?HTa*&L+U;g(woZ=nqr%ХgQ#oρ̇sP4%@fۥ 5{-A)@2/pF7-U̫czvhԟ [7[f4.K,dO,nQO(1 2?73SM}~|1E雙*>x8⿮# Ug|Ai~&k輓SI9O .'@y\I3> 6Hin DjOrƨgH$ m^\{V,\IÇjQaFn6[a[pɣ+p?qR@Zϒ%yc fMU0CMo!pDX,:^9c@.򿑻Ď Okty{0mc ݿ݃KZW~f*=f; 6;սue4'j cE-*8 <0+sldrczKh W\66~HQ6ڙP)鼂qq2!\H[l |mXwvl"~5k+k,\55Hև#qgI}Jf^"znnL=@Z٩לl~6vcllšg1Bp t0:fcjdu!HLpA{}9΅zX/Ռͭ'F6 gf~ǦK4eI=mK3k2)Yimq .%Z+xlj\Zq9nACa VYBuU'ZHW7t1 Nh~Ȟ %+-6-ŵqZftK5[2ЩW%:Y,Ν= ˩UږہY<{i cS$kKc\jFn--yY-u YrBNx׍aFrmdw3?nW+˝xMVLcYɐe+äUt6*ltH%%n֎PחVAe//#\#?*1;2μ"`j Y67GMxidt<]G b3K'Ȼz;N K]

虚函数和普通函数的区别在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对这里是没
虚函数和普通函数的区别

在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对

这里是没在animal类的breathe()里加上virtual前的代码段,输出结果为animal breathe

在加上以后,输出结果为fish breathe

因此我自己的总结是:虚函数是由指针地址中的数据类型来判断函数使用,而非虚函数则是仅仅看指针类型来调用;因此在非虚的情况下调用的是Animal类型,因为指针也是animal类型;而在虚函数的情况下调用的是fish类型的breathe().

不知道以上的思路是否正确?如果不对的话还请帮忙指出错在哪里?


虚函数和普通函数的区别在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对这里是没
class Animal
{
 public:
  virtual void Func1();
};
class Fish : public Animal
{
 public:
  virtual void Func1();
  void Func2();
};
int main( int argc, char *argv[] )
{
 Animal *an;
 Fish *fi;
 return 0;
}
--> 第一类: 
最简单的 an可以调用Func1(); fi可以调用Func1(); Fun1(); (用的都是自己的)
--> 第二类: 
如果设置 an = fi; 结论是: an可以调用Func1(); fi可以调用Func1(); Func2();
如上两种情况所说 其实给进行 an = fi; 其实没啥大用, 因为他们都调用了自己的函数;
但是有一种情况我们是需要解决的 我们希望使用父类的指针来模拟子类的行为
或者说 我们希望使用一根父类的指针 来调用我们在子类里"覆盖"了的函数
那么我们需要使用 "虚函数";  
这样我们就可以使用一根父类的an指针 然后来模拟在子类中被 "override" 的函数 Func1();
这就是多态, 在未引入"虚函数"之前 父类总会根据内存模型来调用父类的函数;
引入了"虚函数"之后 父类就会(在运行时采用 "迟绑定")去检查 是否有子类override了父类的virtual函数;
然后确定 调用的是哪一个函数 ( 子类的? 父类的?  "子类优先" );
 "多态的实现":
 当编译器发现一个类中有虚函数时;就会为这个类自动生成一个"虚表" ; 该表是一个一维数组,在这个数组中存放每个虚函数的地址
 而且会生成一个"指向虚表指针"; 那么对于父类Animal有一个"虚表", 子类Fish由于一定有虚函数所以也有一个"虚表"
 现在在来结合上面的信息; "编译器按照an的内存结构来解释fi"; 这里就发生了"两个动作": ( an小fi大 才会截断 大给小 ok 小给大 GG )
 第一个是"内存的截断": 这就解释了为什么fi自己的函数 这里用不了了; 因为内存截断了,( 对于an, fi自己的子类部分成垃圾了 )
 第二个是"虚表指针改变": 一开始an的虚表指针应该指向着自己的虚函数, fi的虚表指针也指向了自己的虚函数;
 而此时an指向了fi子类对象 当按照an的内存结构解释fi时 解释到的是fi的"虚表"; 所以调用到了fi的虚函数;
类里面的东西非常复杂  .     不是那么简单的判断而已