C++ virtual function behavior - c++

I am doing some exercise on my understanding. on compiling below code I get Derived::disp() called and which in turn calls non-virtual function "Print".
My question is why Derived class "Print"version is called instead of Base print version even "Print" is not virtual.
class Base
{
public:
void print(){
cout<<"Base::Print()\n";
}
virtual void disp(){
cout<<"Base::Disp()\n";
}
};
class Derived: public Base
{
public:
void print(){
cout<<"Derived::Print()\n";
}
void disp(){
cout<<"Derived::Disp()\n";
print();
}
};
void main()
{
Base *pB = new Derived();
pB->disp();
}
output:
Derived::Disp()
Derived::Print()

If you have a call to a NON-virtual function inside a (virtual or non-virtual) member function, the member function of that class is called.
If you were to call pB->print() in main, it would call Base::Print. But as it stands, the pB->Disp() calls Derived::Disp() which calls Derived::Print on the basis that it is called from inside the Derived class.

Within the body of a non-static member function the keyword this has the type of pointer to the object of the class type for which the function is called.
If a virtual function is called for a derived class then this has the type of the pointer of this class.
Inside member functions access to class members looks for example in the context of your program like
( *this ).print();
where this has type Derived *.
Thus member function print of this class is called.

Related

How a friend function of a base class is calling the overridden virtual function of derived class even though they are private ?(C++)

My code-
class base{
private:
virtual void print(){
cout<<" from base"<<endl;
}
friend void show(base &obj);
};
class drived1 : public base{
private:
void print(){
cout<<" from drived1"<<endl;
}
};
class drived2 : public base{
private:
void print(){
cout<<" from drived2"<<endl;
}
};
void show(base &obj){
obj.print();
}
int main() {
base b;
drived1 d1;
drived2 d2;
show(b);
show(d1);
show(d2);
}
Output:
from base
from drived1 // print function form derived class is called, though it is private.
from drived2 // print function form derived class is called, though it is private.
show(base &obj) is a friend function of base class, but how it is calling the private method from derived class?
This is how C++ works. Access specifiers (public, private, and protected) depend on the static type of your variable, not the dynamic type. In your example, when
void show(base &obj){
obj.print();
}
is compiled, the compiler does not know that the function will be invoked with a drived1 argument. It knows that obj is of type base&, so it only checks whether it can invoke base::print() - which it can because it is a friend of base.
It is calling the private method from derived class because the derived class is being implicitly converted to base class when you call the function.
So, you have an object of type drived1.
Then you pass it to the function show(base&).
The object is being upcasted to base.
Then, in the function show(base&) you use the virtual function print().
The function called is the drived1::print() member function thanks to the way C++ polymorphic behavior works. (A class is called polymorphic if it contains virtual functions).
This function is called and you get output from drived1.

virtual function with parameter as class pointer

class A
{
public:
virtual void display_A(A* obja)
{
cout<<"Class A"<<endl;
}
};
class B:public A
{
public:
void display_A(B* objb)
{
cout<<"Class B"<<endl;
}
};
int main()
{
A AOBJ;
B BOBJ;
A *obja = new B();
obja->display_A(&AOBJ);
obja->display_A(&BOBJ);
return 0;
}
There is a virtual function in class A having parameter as A* and we are overriding the same function in the derived class B with parameter B*.
I have created a pointer obja (pointer to class A) which is pointing to derived class object B. When I am calling the function display_A with obja pointer with argument as class A object pointer and class B object pointer, I am getting o/p as
Class A
Class A
I am unable to understand why I am getting that o/p.
It's not overriding because the parameter's type is not the same.
If some member function vf is declared as virtual in a class Base, and
some class Derived, which is derived, directly or indirectly, from
Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or
not the keyword virtual is used in its declaration) and overrides
Base::vf (whether or not the word override is used in its
declaration).
Using override specifier could help you find the error at compile time.
Specifies that a virtual function overrides another virtual function.
In a member function declaration or definition, override ensures that the function is virtual and is overriding a virtual function from the base class. The program is ill-formed (a compile-time error is generated) if this is not true.
class B:public A
{
public:
void display_A(B* objb) override
// ^^^^^^^^
{
cout<<"Class B"<<endl;
}
};
When calling display_A via an A*, either a virtual func of A or B or a non-virtual func of A is called. Since the prototypes are different, the only function matching this criteria is A::display_A.

Virtual function call from a normal function

class base
{
public:
void virtual func(){cout<<"base";}
void check()
{
func();
}
};
class derived: public base
{
public:
void func(){cout<<"dervied";}
};
int main()
{
base *obj = new derived();
obj->check();
return 0;
}
Above code prints derived on the console.
Now, I understand the concept of virtual functions but I'm unable to apply it here. In my understanding whenever we call a virtual function, compiler modifies the call to "this->vptr->virtualfunc()" and that's how most heavily derived's class function gets invoked. But in this case, since check() is not a virtual function, how does the compiler determine that it needs to invoke func() of derived?
how does the compiler determine that it needs to invoke func() of derived?
In the same exat way - by invoking this->vptr->virtualfunc(). Recall that this belongs to the derived class even inside the base class, because each derived class is a base class as well, so the same way of accessing virtual functions works for it too.
Exactly the way you said, by using the vptr in the class member. It knows the function is virtual, therefore it knows it has to call it through the virtual function table.

Calling a virtual method from a base class method

I want to call a overridden method from a base class method called by the derived class:
class Base {
Base();
virtual void function override() {}
void basefunction() {
override();
}
class Derived : public Base {
Derived() {
basefunction();
}
virtual void function override() {
cout << "derived" << endl;
}
}
main() {
Base* d = new Derived();
}
The constructor of Derived call the basefunction, which should call the overridden function "override()"from the derived class.
But it doesn't. It calls Base::override(). I understand why this function is called, but how can I implement my issue, that the basefunction calls the override function from the derived class?
If the override function is defined as pure virtual the declaration in the main function is not allowed.
Is it possible to show us the code you are using? The one you give has to be completed in order to be compilable.
When completed in the obvious way, I get the result I expect: display of "derived".
There is something related which could be the problem you see, or it could be unrelated. During the execution of the constructor and the destructor, the dynamic type is the same as the type of the constructor/destructor. So if you have the call to basefunction in Base() instead of in Derived(), indeed it is Base::override which is called and not Derived::override. During the execution of Base::Base(), Derived's members have not been constructed yet and it would be dangerous to call a member which could access them.

Redifinition of functions in derived class

In C++ primer plus it is written that
"If you redefine just one version of function in derived class, the other functions of base class become hidden and cannot be used by objects of the derived class."
Then why does this code call fun1() ,as it should be hidden for the derived class object i.e. obj.
#include<iostream>
using namespace std;
class base
{
public:
void fun1()
{
cout<<"base"<<endl;
}
void fun2(int a)
{
cout<<"function2";
}
};
class derived :public base
{
public:
void fun2()
{
cout<<"fun2";
}
};
int main()
{
derived obj;
obj.fun1();
}
When it says "the other functions of the base class become hidden" it actually means "the base class functions with the same name become hidden in the derived class".
So, if you declare two overloaded versions of fun1 in the base class (say, fun1(void) and fun1(int)), and then declare another version of fun1 in the derived class (say, fun1(double)), the function in the derived class will hide both fun1 functions inherited from the base class.
In your example, the derived fun2 hides the base fun2, but it doesn't hide base fun1. This is why you can successfully call fun1 in your example.
You can observe the fact that derived fun2 has hidden the base fun2 by trying to call
obj.fun2(42);
Since the fun2(int) from the base class is hidden by fun2(void) from the derived class, the call will fail to compile.
In the above example you have not redefined fun1, but redefined fun2. so if you call fun1 it would still call the base class function. but if you call obj.fun2() it will class derived class function.
You haven't redefined any version of fun1; you have only overloaded fun2. This doesn't hide everything in the base class; it hides the other overloads of the same function.
if you want a function in a derived class do something different to the parent class then you need to make the parent function virtual.
virtual void fun1() { ... }