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.
Related
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.
This question already has an answer here:
method in the derived class got executed without a *virtual* keyword in the referred class
(1 answer)
Closed 2 years ago.
Probably, i misunderstood c++ polymorphism(virtual function).
Please point me what i miss.
the source code is below
#include <iostream>
using namespace std;
class A {
public:
virtual void print(void) {
cout<<"class A"<<endl;
}
};
class B : public A {
public:
void print(void) {
cout<<"class B"<<endl;
}
};
class C : public B {
public:
void print(void) {
cout<<"class C"<<endl;
}
};
int main() {
A a;
B b;
C c;
A *pAa = &a;
A *pAb = &b;
A *pAc = &c;
B *pBc = &c;
pAa->print();
pAb->print();
pAc->print();
pBc->print(); // shouldn't be "class B"
return 0;
}
result
------------------------------
class A
class B
class C
class C // shouldn't be "class B"
my understanding is that
the last print statement should print "class B"
because pBc is a pointer of class B and the print function in class B is non virtual member function. i could not find the answer about this situation.
please tell me why or point me where i can find the answer and
understand c++ polymorphism in comprehension.
thanks.
If a function with a given signature is declared as virtual in a top-level base class, then the function is virtual in all derived classes no matter if it is marked with the keyword virtual (override, final) or not:
virtual function specifier
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration)
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function, even if it
// is not marked as virtual (override, or final).
void foo() const {}
};
In A, adding the virtual specifier to foo() would only bring semantic value; it will be no functional difference whether virtual is omitted or not (unless someone changes the interface in Base).
Many static analyzers enforce(1) marking derived virtual functions with override or final, for two reasons:
semantics; clearly showing the given function is a virtual function (as per being defined so higher up in the inheritance chain), and
enforcement; if a function is marked as override and final but is not actually an overriding function, you will get a compiler error, which can be particularly useful to protect against mistakes when changing a base class interface (whilst forgetting which classes that actually implements this interface).
E.g.:
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function.
void foo() const override {}
};
struct B final : public Base {
// Overriding (final) virtual function.
void foo() const final {}
// Error: Function does not override.
// void bar() const override {}
};
(1) E.g. Rule A10-3-1 in the Autsar C++14 Language Guidelines (safety-critical development in automotive) is categorized as a required rule: Virtual function declaration shall contain exactly one of the three specifiers:(1) virtual, (2) override, (3) final.
the print function in class B is non virtual member function
No. Since A::print is marked as virtual and B inherits from A, then B::print is virtual too; regardless of the keywork virtual is specified on it or not.
(emphasis mine)
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).
class Base {
public:
virtual void f();
void f(int);
virtual ~Base();
};
class Derived : public Base {
public:
void f();
};
int main()
{
Derived *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
ptr->f(1); is showing the following error: "too many arguments in function call".
Why is this isn't possible? isn't derived inherited all the functions form base and is free to use any of them?
I could call it explicitly and it would work but why isn't this allowed?
What you are seeing is called hiding.
When you override the function void f() in the Derived class, you hide all other variants of the f function in the Base class.
You can solve this with the using keyword:
class Derived : public Base {
public:
using Base::f; // Pull all `f` symbols from the base class into the scope of this class
void f() override; // Override the non-argument version
};
As mentioned by #Some Programming Dude : it is because of Hiding.
To understand hiding in relatively simpler language
Inheritance is meant to bring Baseclass variables / functions in Derived class.
But, on 1 condition : "If its not already available in Derived Class"
Since f() is already available in Derived, it doesn't make sense to look at Base class from compiler perspective.
That's the precise reason why you need to scope clarify while calling this function
void main()
{
Derived *ptr = new Derived;
ptr->Base::f(1);
delete ptr;
}
Suppose for time being that Derived do have the access to the function void Base::f(int);. Then it will be a case of function overloading. But, this is invalid case of function overloading since one function f(int);is in Base and other function f(); is in Derived. Function Overloading happens inside a single class. Function Overriding happens across classes. The example you posted is a case of Name Hiding in Inheritance
"Derived *ptr" This definition will only allow "ptr" to access all the member functions which are defined via Derived class or its child class. But, it will not allow u to access the member functions which are coming in Derived class because of inheritance.
If u want to access base class version of function "f" then use "Base *ptr" and it will choose the correct version of function automatically as shown :)
class Base {
public:
virtual void f()
{
cout<<"Here 2"<<endl;
}
void f(int x)
{
cout<<"Here 1"<<endl;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
void f()
{
cout<<"Here 3"<<endl;
}
virtual ~Derived() {}
};
int main()
{
Base *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
output is
Here 1
Please see the output of this function function . It shows static functions can be overridden because derived class inherits function:
void put(){printf("Static functions in base class");}
if we dont override put() output is Static functions in base class
but we override it to be:
void put(){printf("Static functions are overridden in derived class");}
So output is Static functions are overridden in derived class
public:
#include<iostream>
class base{
public:
static void put(){printf("Static functions in base class");}
};
class derived : public base{
void put(){printf("Static functions are overridden in derived
class");}
};
int main(){
derived *bp = new derived;// Static Polymorphism //
bp->put();
return 0;
}
Since here put() is not a virtual function . SO can we override functions which are not virtual ?
Is it a case of static polymorphism ?
Can static functions be overridden?
No.
struct Base { static void f() {} };
struct Derived : Base { void f() {} };
Base::f and Derived::f are two distinct functions who don't even share a common interface: the proper takes no argument, the later an hidden pointer to a Derived.
Can non virtual functions be overridden?
No.
struct Base { void f() {} };
struct Derived : Base { void f() {} };
Derived::f hides Base::f when you manipulate an object, a reference to an object or a pointer to an object of type Derived:
Derived d;
Derived& dref = d;
Derived* dptr = &d;
d.f(); // calls Derived::f
dref.f(); // calls Derived::f
dptr->f(); // calls Derived::f
Base& bref = d;
Base* bptr = &d;
bref.f(); // calls Base::f
bptr ->f(); // calls Base::f
No, this is not a case of static polymorphism: there is no "override" here, because the function invocation is completely resolved at compile time.
The compiler knows that bp's type is derived*, so it invokes the static member function derived::put. Had the compile-time type of bp been base*, base::put would have been invoked - demo:
base *bp = new derived;
bp->put(); // prints "Static functions in base class"
That is why invoking static functions through instance pointers is misleading. The call in your code is equivalent to derived::put(), but the readers of your code must trace the type to the declaration in order to see that.
No. Neither static member function, nor non virtual member function could be overrided.
For you case, if you change the type of bp to base*, you'll see the result will be
Static functions in base class
The static member function could not be overrided, they behavior like free function, doesn't depend on object, doesn't use this pointer implicitly. Which function will be called is determined by the static type.
LIVE
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.