Let’s look at the example first, what will be the output?

    1. #include <iostream>
    2. #include <string>
    3. using namespace std;
    4. class Person
    5. {
    6. public:
    7. string name;
    8. Person(string n) : name(n) {}
    9. virtual void print()
    10. {
    11. cout << "Name: " << name << endl;
    12. }
    13. };
    14. class Person2
    15. {
    16. public:
    17. string name;
    18. Person2(string n) : name(n) {}
    19. virtual void print() = 0;
    20. };
    21. class Student : public Person
    22. {
    23. public:
    24. string id;
    25. Student(string n, string i) : Person(n), id(i) {}
    26. void print()
    27. {
    28. cout << "Name: " << name;
    29. cout << ". ID: " << id << endl;
    30. }
    31. };
    32. void printObjectInfo(Person &p)
    33. {
    34. p.print();
    35. }
    36. int main()
    37. {
    38. {
    39. Student stu("yu", "2019");
    40. printObjectInfo(stu);
    41. }
    42. {
    43. Person *p = new Student("xue", "2020");
    44. p->print(); // if print() is not a virtual function, different output
    45. delete p; // if its destructor is not virtual
    46. }
    47. // { //if you want to call a function in the base class
    48. // Student stu("li", "2021");
    49. // stu.Person::print();
    50. // Person * p = new Student("xue", "2020");
    51. // p->Person::print();
    52. // delete p;
    53. // }
    54. return 0;
    55. }
    • But if we define print() function as a virtual function, the output will be different.
    • Static binding: the compiler decides which function to call
    • Dynamic binding: the called function is decided at runtime.
    • Keyword virtual makes the function virtual for the base and all derived classes.

    Virtual Destructors
    If a virtual destructor is not virtual, only the destructor of the base class is executed in the follow examples.
    析构函数一定是虚函数

    1. Person * p = new Student("xue", "2020");
    2. p->print();
    3. ...
    4. ...
    5. delete p; //if its destructor is not virtual