简体   繁体   中英

virtual function and derived class

Let me show you the simple C++ code example first.

#include <iostream> 
using namespace std;

class Person{

  string m_name;
public:
  virtual void saySomething(){
    cout << "I am a person.";
  }
};

class Student:public Person{
public:

  void saySomething(){
    cout << "I am a student." << endl;
  }
};

class CSStudent:public Student{
public:

  void saySomething(){
    cout << "I am a CS Student." << endl;
  }
};

int main(){
  Person* p = new Person();
  Student* s = new Student();
  CSStudent* c = new CSStudent();

  ((Student*)c)->saySomething();

  return 0;
}

In my example, Student is a derived class of Person. Also, CSStudent is a derived class of Student. I know virtual keyword make it possible to determine if it is derived class.

Question 1.

((Student*)c)->saySomething();

Why do I get "I am a CS Student."? I expected "I am a Student." since I specify virtual keyword only for the Person.

Question 2.

I saw an example that puts a virtual keyword to only base case. Also, I saw an example that puts virtual keywords to all base case and derived classes. What's the difference between these two?

Question 3.

virtual function is determined in run time. What about non-virtual function? Is it determined in compile time?

For the first question, even if you cast c to another class based on the same base-class, it's still the original class (ie CSStudent ). Virtual functions are (almost always) implemented through a jump table. So the c object have a table which contains the address to the actual function in the c object. This table will not change because you re-cast the type.

For the second question, there is no difference. If you mark a member function as virtual in the base class, it will be virtual in all child-classes as well. It's just that some people prefer to mark the functions in the child-classes virtual too. It can actually be good because then you don't have to check the base-class to see which functions are virtual and which are not.

And for the third question. Yes, virtual functions are calculated runtime using the table as described above, while non-virtual functions are determined at compilation time.

Question 1.

((Student*)c)->saySomething();

Why do I get "I am a CS Student."? I expected "I am a Student." since I specify virtual keyword only for the Person.

In C++, if the base class specifies that a function is virtual , then you don't need the virtual keyword in any derived classes for member functions with the same signature. You can include it if you want to (and it's generally good practice to do so), but it's optional.

Question 2.

I saw some example on the web page that mentions virtual keyword to only base case. Also, I saw some example that mentions virtual keyword to all base case and derived classes. What's the difference between these two?

As above: there is no difference. If the base class says a method with a particular signature is virtual, then that applies to all derived classes too.

Question 3.

virtual function is determined in run time. What about non-virtual function? Is it determined in compile time?

Yes. If your saySomething() function was non-virtual, then the calls would be resolved at compile-time, and the cast to Student* would mean you'd get the Student version of saySomething() .

Why do I get "I am a CS Student."? I expected "I am a Student." since I specify virtual keyword only for the Person.

In C++, if you specify the virtual keyword in a base class, that method will automatically be made virtual in any subclasses as well. (I won't try to speculate on why C++ works that way, but it does)

I saw an example that puts a virtual keyword to only base case. Also, I saw an example that puts virtual keywords to all base case and derived classes. What's the difference between these two?

Functionally there is no difference. I think stylistically the latter one is a little better in terms of being self-documenting.

virtual function is determined in run time. What about non-virtual function? Is it determined in compile time?

Correct. In particular, the method implementation that gets called for a non-virtual method will be determined solely by the pointer type it was called through, rather than via dynamic lookup of the appropriate subclass method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM