鱼C论坛

 找回密码
 立即注册
查看: 2933|回复: 7

虚方法(virtual method)的意义??

[复制链接]
发表于 2019-6-16 21:13:02 | 显示全部楼层 |阅读模式
20鱼币
虚方法 就是基类的函数前面加个 virtual,类似于 virtual void play();这样的
是为了c++在编译的时候遇到同类型的指针,不直接使用基类的函数(c++为了保证速度,同类型的指针一起处理),
而是等到程序运行的时候根据子类的指针

  1.      
  2. class Pet{
  3. public:
  4.         Pet(std::string theName);
  5.         void play();  //virtual
  6. protected:
  7.         std::string name;
  8. };

  9. Pet::Pet(std::string theName){
  10.         name = theName;
  11. }

  12. void Pet::play(){
  13.         std::cout << name <<"正在玩\n";
  14. }

  15. class Cat :public Pet{
  16. public:
  17.         Cat(std::string theName);
  18.         void play();
  19. };
  20. Cat::Cat(std::string theName) :Pet(theName){

  21. }

  22. void Cat::play(){
  23.         std::cout << name <<"正在爬树\n";
  24. }

  25. class Mouse :public Pet{
  26. public:
  27.         Mouse(std::string theName);
  28.         void play();
  29. };
  30. Mouse::Mouse(std::string theName) :Pet(theName){

  31. }

  32. void Mouse::play(){
  33.         std::cout << name <<"正在偷奶酪\n";
  34. }

  35. int main(){
  36. Pet *cat = new Cat("Tom");
  37.         Pet *mouse = new Mouse("Jerry");

  38.         cat->play();
  39.         mouse->play();
  40. }
复制代码

上面代码运行时,cat和mouse在编译过程中都是pet类型的指针会一起执行pet::play()这个函数,
通过在Pet类里加virtual就可以分别使用cat和mouse 里的play了,virtual void play();

但是我这样改
Cat *cat = new Cat("Tom");
Mouse *mouse = new Mouse("Jerry");
不用加virtual,结果完全正确

感觉这个虚函数非常鸡肋,明明指针赋值的时候小心一点就可以了,有大神出来说说我这样改会有什么问题吗

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-16 21:24:47 | 显示全部楼层
1, 虚函数的作用主要用来支持后边要学习的多态。
2, 想想看,你的宠物不止是猫和老鼠还有其他一堆,如果都要去分别调用play()岂不是很累,这时候就需要另外一个函数了,具体慢慢学,到多态就明白了哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-17 09:20:11 | 显示全部楼层
研究一下C++的图形库,就会深有感触
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-18 08:13:14 | 显示全部楼层
正在看中,感觉有点难
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-7-19 12:31:14 | 显示全部楼层
AmosAlbert 发表于 2019-7-19 12:30
塔克一点都不鸡肋哦  虚函数一般存在于基类中。纯虚函数更是构成了虚基类,虚基类的作用就是用来被派生的, ...


还有重载也算多态的一种吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-7-19 13:52:13 | 显示全部楼层
对于这个问题来说,这样改是没有问题的,c/c++是按模块(函数)编译的,也就是说,编译后的汇编形式与是否使用虚函数几乎没有差别,一个具体的函数会有一个具体的指针,如果在c语言里,可以用函数指针数组模拟多态,但是c++是面向对象设计的,而多态是面向对象的一大特征,c++编译器可以正确的选择实现函数来编译,方便了程序的编写过程。
如题,若要依次PET类的数组中不同子类的play方法,就可以一个循环搞定,而不需要再用子类分别调用方法。
至于编译器是如何具体实现条用不同函数实现的,就不太清楚了,盲猜还是用指针数组的方式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-7-20 16:05:22 | 显示全部楼层
虚函数,是多层继承,才会用到的东西
比如 class a 有一个属性 高度,class b 继承 a,class c 继承a,class d 同时继承 b,c,不用虚函数,d就有两个高度
调用时就不知道用啥了,会报错
大概就是这样的意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-8-1 15:38:20 | 显示全部楼层


虚函数的本质是通过基类访问派生类定义的函数。

虚函数只能借助于指针或者引用来达到多态效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 10:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表