Suppose I define a base class and a derived class in the following way:
1 2 3 4 5
// the base class
class base{
virtualvoid fa() = 0;
void fb(){fa();}
}
1 2 3 4
// the derived class
class derived: public base{
void fa() {...}
}
In the main function:
1 2 3 4 5
int main(){
derived* p;
p->fb();
...
}
My question: when the main function is calling the function fb() by using a pointer to an instantiation of the derived class, will fb() automatically incur the fa() defined in the derived class?
Do you know what a pure virtual function is? It is a function with no definition, meaning that it is syntactically illegal to call it and it also makes it so you cannot have an instance of the class. The only way to get an instance of the class is to derive from it, implement the function, and THEN you can get an instance.
Obviously the code you posted would do either one of two things:
1. Fail to compile from trying to call a pure virtual function, or
2. Compile and call the most derived virtual-overridden version of the function.
To confirm, what you are trying to do is perfectly legal and acceptable. That's how virtual functions work.
The only caveat is that the object has to be fully constructed in order for it to work. That is, trying to call a virtual function from a constructor won't work -- at least not how you expect. Calling from a destructor has a similar problem and also won't work.
Thanks a lot for your comments. It clarifies my concern on if what I am trying to do is legal.
By your second paragraph, do you mean that I have to fully define the ctor and dtor in both the base and derived class? BTW, I don't think that I am implying anything in my pseudo code that I am intent to call the fa() or fb() from the ctor or dtor. Curious why you think that I am going to call these functions from ctor or dtor.
Which pair of ctor and dtor can not call the virtual functions? The pair in the base class or the pair in the derived class or both in base and derived class?
class A
{
public:
A() { TheVirtual(); }
virtual ~A() { TheVirtual(); }
virtualvoid TheVirtual() { cout << "A" << endl; }
};
class B : public A
{
public:
virtualvoid TheVirtual() { cout << "B" << endl; }
};
//...
int main()
{
A* b = new B; // prints "A"
b->TheVirtual(); // prints "B" as expected
delete b; // prints "A"
}
In the destructor, the reason for this is because the B portion of the object has already been destructed by the time A's dtor is called, therefore it can't call a B function, so it calls the A version.
Calling it from the B dtor would print "B", but that would have the same problem if there was a 3rd class (C) which derives from B.
The constructor is the same story. The A portion is constructed first, so the B portion hasn't been constructed when TheVirtual is called, so it can't call the B version of that function.