Home  >  Q&A  >  body text

关于C++的虚方法问题

我在看到C++的虚方法 的时候,怎么突然有种多此一举的感觉。比如有个基类 Class Mammal{};然后又有个派生类 Class Dog : public Mammal {};然后我弄个对象出来 Dog Fido; 按道理来说 Fido这个条狗 就能继承 Mammal这个类 public 里面的所有方法(除了Dog类里面被覆盖的)。

然后我们再来看下 虚方法这个东东。要让虚方法 virtual 起作用, 那么new 出来的 对象 必须要用其基类的指针变量来接收 ,比如: Mammal * Fido = new Dog ;等到 用 Fido来调用方法的时候 首先是先去Mammal里面找 如果找到的函数 是个虚函数,那么久忽略掉这个函数 用Dog(Dog 里面有个同名的函数) 类里面的函数。

当我看到 虚函数的这个作用的时候,我感觉 不都是继承嘛! 还搞这么多花样,在我目前的学习阶段,我主观上没发现该虚方法有什么好处。 大家来谈谈看撒!

伊谢尔伦伊谢尔伦2714 days ago902

reply all(5)I'll reply

  • 天蓬老师

    天蓬老师2017-04-17 14:37:06

    Virtual functions are used for polymorphism. For example, in a game, all players and enemies can inherit the same game character class, and its internal update functions and rendering functions are virtual functions. Use an array of base class pointers to store these different players and enemies, and only need a for loop when updating and rendering, saving a lot of effort.

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-17 14:37:06

    Imagine the following scenario:
    You have a UI library with many components, such as TextEditor, Button, etc., which all use UIBase as their base class;
    Now, you want Traverse all components and find all components Button of type

    Then it can be easily achieved using virtual methods:
    First add a virtual method UIBase to char* GetType() (in this example, it is actually more appropriate to add a pure virtual method), and then each subclass All rewrite GetType(), for example, the Button class is rewritten as char* GetType(){return "Button";}

    Since I can use the base class pointer to save subclass objects, then I only need to maintain an array UIBase *a[] and add it to a every time I create a new element. Then back to my needs, I just need to execute for(k in a) if(k->GetType()=="Button"){...}

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 14:37:06

    C++ virtual function: an essential part of the implementation of polymorphism. Polymorphic? -> The highest level of code reuse, engineering significance, calling the future.

    C++ does not have an interface, how to implement it? Pure virtual function interface class.

    Virtual destruction, interface encapsulation and design.

    Principle: Dynamic chaining

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 14:37:06

    For example:

    For example, if Mammal and Dog both define virtual functions virtual void do(). At this point you define a function

    void fun(Mammal * ani)
    {
        ani->do();
    }
    
    Mammal * ani = new Dog();
    fun(ani);

    At this time, the parameters can be passed in the Mammal or Dog object pointer. As shown in the previous code, since the actual type of the object pointed to by the ani pointer is Dog, when calling ani->do(), since do is a virtual method, Dog::do() will be called.

    But if do is not a virtual method, then ani->do() will actually execute Mammal::do();

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-17 14:37:06

    About these things, there is a more detailed description in the book "In-depth Exploration of the C++ Object Model".
    Virtual functions involve runtime binding, while non-virtual functions involve compile-time binding.
    Give me an example.

    #include <iostream>
    using namespace std;
    class A{
      public:
      void f1(){cout<<"A::f1"<<endl;}
      virtual void f2(){cout<<"A::f2"<<endl;}
    };
    
    class B:public A{
      public:
      void f1(){cout<<"B::f1"<<endl;}
      virtual void f2(){cout<<"B::f2"<<endl;}
    };
    
    class C:public A{
      public:
      void f1(){cout<<"C::f1"<<endl;}
      virtual void f2(){cout<<"C::f2"<<endl;}
    };
    
    int main()
    {
      A* p = 0;
      char t;
      cin>>t;
      switch(t){
        case 'B':
        case 'b':
          p = new B;break;
        case 'C':
        case 'c':
          p = new C;break;
        case 'A':
        case 'a':
        default:
          p = new A;
      }
      p->f1();    // 这里将始终输出 A::f1,编译时候就确定了
      p->f2();    // 这里是在运行时才能确定的
                  // p指向的对象中包含虚函数指针,指向虚函数表
                  // 调用f2的时候是根据这个指针去确定使用哪一个的
    }

    reply
    0
  • Cancelreply