虚函数和普通函数的区别在VC++深入详解里复习了virtual关键词,然而上次接触这个关键词已经有段时间了,这次虽然似乎是明白了但是希望用自己的话总结一下,但不知道总结的对不对这里是没
来源:学生作业帮助网 编辑:作业帮 时间:2024/11/05 18:44:15
虚函数和普通函数的区别在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的虚函数;
类里面的东西非常复杂 . 不是那么简单的判断而已