Why do we need virtual functions in C++?

前端 未结 26 3108
北恋
北恋 2020-11-21 05:50

I\'m learning C++ and I\'m just getting into virtual functions.

From what I\'ve read (in the book and online), virtual functions are functions in the base class that

26条回答
  •  伪装坚强ぢ
    2020-11-21 06:10

    Here is a merged version of the C++ code for the first two answers.

    #include        
    #include        
    
    using   namespace       std;
    
    class   Animal
    {
            public:
    #ifdef  VIRTUAL
                    virtual string  says()  {       return  "??";   }
    #else
                    string  says()  {       return  "??";   }
    #endif
    };
    
    class   Dog:    public Animal
    {
            public:
                    string  says()  {       return  "woof"; }
    };
    
    string  func(Animal *a)
    {
            return  a->says();
    }
    
    int     main()
    {
            Animal  *a = new Animal();
            Dog     *d = new Dog();
            Animal  *ad = d;
    
            cout << "Animal a says\t\t" << a->says() << endl;
            cout << "Dog d says\t\t" << d->says() << endl;
            cout << "Animal dog ad says\t" << ad->says() << endl;
    
            cout << "func(a) :\t\t" <<      func(a) <<      endl;
            cout << "func(d) :\t\t" <<      func(d) <<      endl;
            cout << "func(ad):\t\t" <<      func(ad)<<      endl;
    }
    

    Two different results are:

    Without #define virtual, it binds at compile time. Animal *ad and func(Animal *) all point to the Animal's says() method.

    $ g++ virtual.cpp -o virtual
    $ ./virtual 
    Animal a says       ??
    Dog d says      woof
    Animal dog ad says  ??
    func(a) :       ??
    func(d) :       ??
    func(ad):       ??
    

    With #define virtual, it binds at run time. Dog *d, Animal *ad and func(Animal *) point/refer to the Dog's says() method as Dog is their object type. Unless [Dog's says() "woof"] method is not defined, it will be the one searched first in the class tree, i.e. derived classes may override methods of their base classes [Animal's says()].

    $ g++ virtual.cpp -D VIRTUAL -o virtual
    $ ./virtual 
    Animal a says       ??
    Dog d says      woof
    Animal dog ad says  woof
    func(a) :       ??
    func(d) :       woof
    func(ad):       woof
    

    It is interesting to note that all class attributes (data and methods) in Python are effectively virtual. Since all objects are dynamically created at runtime, there is no type declaration or a need for keyword virtual. Below is Python's version of code:

    class   Animal:
            def     says(self):
                    return  "??"
    
    class   Dog(Animal):
            def     says(self):
                    return  "woof"
    
    def     func(a):
            return  a.says()
    
    if      __name__ == "__main__":
    
            a = Animal()
            d = Dog()
            ad = d  #       dynamic typing by assignment
    
            print("Animal a says\t\t{}".format(a.says()))
            print("Dog d says\t\t{}".format(d.says()))
            print("Animal dog ad says\t{}".format(ad.says()))
    
            print("func(a) :\t\t{}".format(func(a)))
            print("func(d) :\t\t{}".format(func(d)))
            print("func(ad):\t\t{}".format(func(ad)))
    

    The output is:

    Animal a says       ??
    Dog d says      woof
    Animal dog ad says  woof
    func(a) :       ??
    func(d) :       woof
    func(ad):       woof
    

    which is identical to C++'s virtual define. Note that d and ad are two different pointer variables referring/pointing to the same Dog instance. The expression (ad is d) returns True and their values are the same <main.Dog object at 0xb79f72cc>.

提交回复
热议问题