In this code I am storing the address of object B in pointer type object of A.
If I call the function then the program must run the function of second class but it doesn't work and run function of 1st class.
If I put virtual before the parental class function then it moves towards other class function.
When I stored 2nd class address in pointer type object, program have to show 2nd class function. But it couldn't do this.
Why this is so?
#include<iostream>
using namespace std;
#include<conio.h>
class a
{
public:
void fun()
{
cout << "1st";
}
};
class b:public a
{
public:
void fun()
{
cout << "2nd";
}
};
class c :public a
{
public:
void fun()
{
cout << "3rd";
}
};
void main()
{
a *A;
b B;
c C;
A = &B;
A->fun();
_getch();
}
When i stored 2nd class address in pointer type object, program have to show 2nd class function...
Not, it does not. In C++ functions are associated with classes (types), not objects. So compiler looks at the type of the pointer your functions is called through. Then, it tries to find such function in the corresponding class definition.
In your case compiler sees "call to the function fun() through the pointer of type A" and it simply translates it to the address of fun() from class A.
*The callable function is stored elsewhere, but not inside the object.
Indeed, this is the point of "statically typed" languages: compiler looks at your object through the prism of the object`s type.
However, as was mentioned, if you want to make association of a function with particular object, you need to use the keyword virtual. This will create a virtual table for each object of class A (and all inherited from A). Then addresses of all functions marked is virtual will be stored inside this virtual table. Consequently, when inheriting class has its own implementation of a virtual function, the address of the new implementation will override the previous address inside the object`s virtual table.
Now, when you call fun() through the pointer of class A the control flow (now during the runtime) will make a lookup to the objects virtual table and will find an address to the function you expect.
class A
{
public:
virtual void fun()
{
cout << "1st";
}
};
class B
{
public:
void func() override
{
cout << "2nd";
}
}
void main()
{
a *A;
b B;
A = &B;
A->fun(); // -> "2nd"
// function address deduced at runtime
}
You need to use virtual keyword, otherwise inheritance might not work as you expected.
So change your class a as follows:
class a
{
public:
virtual void fun()
{
In c++, pointers are static. This means that they are always looking for the parent's functions, even if they are pointing to a child class. You can avoid this by declaring a:fun as virtual. Take a look at this:
http://www.cplusplus.com/doc/tutorial/polymorphism/
Related
This question already has answers here:
Downcasting using the 'static_cast' in C++
(3 answers)
Closed 3 years ago.
I have the below piece of code where I have a base class and a derived class. Both base class and derived class are having a function member sharing the same name. In the main(), I have typecasted a base class object to a derived class pointer and trying to call the function. To my utter surprise, it is calling the derived class function member. As far as I know, the base class object won't be having any information about the derived class object. So, how come my derived class pointer is still able to access the derived member function?
In the case of upcasting, I do understand derived class object will be having the contents of the base class that's why a base class pointer pointing to a derived class object will work as expected.
Can someone please help me in understanding how the derived class member function is getting called in this even when I am having a derived class pointer pointing to a base class object(which is having no information of derived class)?
#include<iostream>
using namespace std;
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
public:
void b()
{
cout << "derived";
}
};
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
d1->b();
return 0;
}
In your specific case, it's perfectly normal that b is called.
You have a pointer to Derived class, b it's not virtual. So the compiler will generate a call to Derived::b method.
Now, when b will be executed, as you put crap in the this pointer, it's undefined behavior.
But in your case, as you do not access the this pointer, there's no probleme.
Cast a base class to derived class results undefined behavior
As I know, the function doesn't takes any extra space in memory, it stores like the normal function. You can see a member function as a normal function with an extra this pointer. In general, which function to call is determined by the type of the object pointer. But the virtual function is different, it is called by virtual function table, in your code, there is no virtual function declared. So there is no virtual function table.
You can see your code in a different way:
void derived_b(derived* this)
{
cout << "derived";
}
void base_b(base* this)
{
cout << "base";
}
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
derived_b(d1);
return 0;
}
If you define some member in class, and use it in function b, it may cause some error.like
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
int a;
public:
derived(){a = 1;}
void b()
{
cout << "derived" << a;
}
};
your code in main() may cause error because the object b don't have any member in memory.
Let's say i have this simple code
#include <iostream>
using namespace std;
class A {
public:
void show() {
cout << "A" << endl;
}
};
class B {
public:
void show() {
cout << "B" << endl;
}
};
class C:public A, public B {
};
int main()
{
C obj;
obj.show();
}
this throws a compile time error because the call to function show() is ambiguous. I want to know how does the compiler understand this? Object creation is a run time process, so, how does the compiler know before hand that an object of Class C is going to be created which would invoke show(). Can anybody please tell me the concept behind this?
You are inheriting both the base classes A and B which has the same method show in C. This is the reason you are facing the compiler error ambiguous access of 'show'.
To get over it, you need to be more explicit on which `show method you would want to invoke. It would be easy to do it using the scope resolution operator.
To invoke show method of A: obj.A::show();
To invoke show method of B: obj.B::show();
This concept is called "Late Binding" in "Polymorphism". It means, the code tells the compiler to understand what to do on runtime. You should use virtual functions in this manner; and it is only available when you use this with "pointers". Let me give you a little example.
class Teacher { //base class
string name;
int numOfStudents;
public:
Teacher( const string &, int ); // constructor of base
virtual void print() const; // a virtual (polymorphic) function
};
class Principal : public Teacher{ // derived class
string SchoolName;
public:
Principal( const string &, int , const string & );
void print() const; // also virtual (polymorphic)
};
If you create a Principal object on main function and then call its print() function, compiler will run the function which is defined in "Principal" class. But if you don't define a print() function in a class which you derived from "Teacher" class, then when you call a print() function of that class' object pointer it will run the print() defined in "Teacher" class.
But again do not try this with the object itself, you should do it with pointers.
Best regards.
Here is the answer you are looking for: obj is of type C which means it is both type A and type B. I am trying to be careful not to say "has-a" when it is "is-a", but, in my mind, an object of type C has also an object of type A and type B. When you call a constructor for type C, you would also call the constructors of type A and B.
So, up to the point of creation of obj, everything is fine. But, after that the compiler has to decide which of the two show()'s to call. And that is when it is getting confused.
You are inheriting from both the classes A and B. That's why it is showing you an error, namely because it is ambiguous. To handle this you can refer explicitly to the function or method should be invoked at the time of calling by the object of the C's object. This way the compiler doesn't get confused and doesn't show any error to you.
CODE :
class A{
public:
void show(){ cout<<"Class A"; }
};
class B{
public:
void show(){ cout<<"Class B"; }
};
class C : public A , public B{
public:
void disp(){ A::show(); } // Here You can make explicit from which class the method
// shall be called. I refer to method "show" from class A.
}
main(){
C obj;
obj.disp(); // Ambiguity in Multiple Inheritance Problem Solved
}
I've read about virtual functions in C++ and understood how they provide the programmer with access to the member function of derived class using a pointer of base class. (aka Polymorphism).
The questions that have been bothering me are:
Why declare a function with a same name in the base class, if in the end it has to be declared virtual? (Note: I need answers with respect to the polymorphism aspect of virtual functions)
In the code below, if 'virtual display()' is called with a base class pointer (Line 22), it shows an error. Why are virtual functions in C++ so rigid w.r.t. not getting called by base class pointers?
.
#include <iostream>
using namespace std;
class B
{
public:
void virtual display()
{ cout<<"Inside base class.\n"; }
};
class D : public B
{
public:
void display()
{ cout<<"Inside derived class.\n"; }
};
int main()
{
B *b;
D d;
//Line-22 b->display(); Why can't 'b' call it's own display()?
b = &d;
b->display();
system("pause");
return 0;
}
Output:
Inside derived class.
b is a pointer not an object. Initially it didn't point to anything (so indirecting through it is an error); after b = &d, it points to a D object, so using it to call a virtual function will call D's override.
The virtual dispatch mechanism is defined so that the function is chosen based on the type of the actual object that the pointer points to, not the declared type of the pointer. So if it pointed to a B object then it would call B::display; here, it points to a D object, so it calls D::display.
Why declare a function with a same name in the base class, if in the end it has to be declared virtual?
It needs to be declared in the base class so that, when using a pointer to the base class, the compiler knows that it exists. Whether calling the function through the pointer will call the base-class version, or a version overridden by a derived class, depends on the type of the object.
In the code below, if virtual display() is called with a base class pointer (Line 22), it shows an error.
That's because it doesn't point to anything, so using it is an error. If it were to point to a B object, then it would call the function declared in B.
B b_obj;
b = &b_obj;
b->display(); // "Inside base class"
Why are virtual functions in C++ so rigid w.r.t. not getting called by base class pointers?
They're not; that's the usual way of calling them. But the pointer must point to a valid object for virtual dispatch to work.
I confess I don't quite understand your question #1. Declaring a virtual function in a base class allows derived classes to override that implementation.
There are tons of uses for this (just search for polymorphism, Liskov substitution etc.). As a simple (and contrived) example, consider this:
struct File
{
virtual void open() { some_code; }
virtual void close() { some_code; }
static std::unique_ptr<File> create();
};
struct DbgFile : File
{
virtual void open() { std::clog << "Opening"; File::open(); }
virtual void open() { std::clog << "Closing"; File::close(); }
};
std::unique_ptr<File> File::create()
{
#ifdef NDEBUG
return { new File };
#else
return { new DbgFile };
#endif
}
int main()
{
auto f = File::create();
f->open();
f->close();
}
The above main() uses the File interface, but in debug builds, it will actually work with an object of type DbgFile which logs all operations happening on it.
As to your question #2, the problem in your code is that b doesn't point anywhere. If you do this instead, it will work just fine:
int main()
{
B *b;
B bb;
D d;
b = &bb;
b->display(); // Outputs "Inside base class."
b = &d;
b->display(); // Outputs "Inside derived class."
// In addition, you can explicitly suppress dynamic dispatch:
b->B::display(); // Outputs "Inside base class."
return 0;
}
Why declare a function with a same name in the base class, if in the end it has to be declared virtual? (Note: I need answers with respect to the polymorphism aspect of virtual functions)
It's necessary because,base class has to know which function definition it needs to call at runtime. Its a kind of interface.
In the code below, if 'virtual display()' is called with a base class pointer (Line 22), it shows an error. Why are virtual functions in C++ so rigid w.r.t. not getting called by base class pointers?
Since the pointer is not initialized its throwing an error. Use like below.
Base baseObj1,*basePtr;
basePtr= &baseObj1;
basePtr->Display(); //Inside base class
I have code which is structured similar to the following:
#include <iostream>
class base
{
public:
void method();
};
class A:public base
{
public:
void method();
};
void base::method()
{
std::cout << "base method\n";
}
void A::method()
{
std::cout << "A method\n";
}
int main()
{
base* array[1];
array[0] = new A;
array[0]->method(); //should call A::method() but it doesnt.
delete array[0];
}
I would like to, whenever i call "method()" using the pointer array call the method belonging to the A class (or any other classes derived from base, pointed to by array[]).
However this code seems to always call the method attached to the class "base".
From what I understand the "method()" defined by the class A should override the "method()" in the base class.
How do i call the method defined in "A" via an array of pointers of type "base"?
Thanks for any help.
You need to declare method() as virtual in order to get this to work.
Without the virtual keyword, the compiler will statically, at compile time, choose to call the method associated with the pointer (or reference) type, as opposed to the object type that the pointer is pointing to.
By declaring the method as virtual, you're instruction the compiler to instead make the selection of which function to call at runtime and call the function not based on the type of the pointer, but the type of the object the pointer is pointing to.
I'm working on C++. Following is my code:
#include <iostream>
using namespace std;
class base
{
public:
virtual void display(int a = 4)
{
cout << "base :: "<< a*a << endl;
}
};
class derived : public base
{
public:
void display(int b = 5)
{
cout << " Derived :: " << b*b*b << endl;
}
};
int main()
{
base *bobj;
derived dobj;
bobj = &dobj;
bobj->display();
return 0;
}
The output is:
Derived :: 64
The function of Base class is called, but default value of the parameter of derived function is used.
Why the derived class method display(), takes the base class method argument value?
Because you're calling it through a pointer to base. That's how it works.
Arguments are pushed on the argument stack (or inside registers) before the actual call. Because you have a pointer to base and no parameters, the default 4 is passed to the function. Then the correct function is called (derived::display), but with base's default parameter. Of course, this is an implementation detail, but the behavior is standard.
C++03 8.4/10
A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static
type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default
arguments from the function it overrides.
I would provide emphasis on the quote, but the whole thing is pretty self-explanatory.
dobj.display();
would print 125 (5^3).
Default arguments are inserted by the caller. Your code is equivalent to
class base {
public:
virtual void display(int a) { cout << "base :: "<< a*a << endl; }
inline void display(void) { display(4); }
};
etc.
When calling through a base pointer, the default value from the base class is inserted.
The Standard says it all:
(§8.3.6/10) A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides. [ Example:
struct A {
virtual void f(int a = 7);
};
struct B : public A {
void f(int a);
};
void m() {
B* pb = new B;
A* pa = pb;
pa->f(); // OK, calls pa->B::f(7)
pb->f(); // error: wrong number of arguments for B::f()
}
— end example ]
Make yourself a less contrived test setup, and it becomes clear:
#include "base.hpp"
int compute(base * p)
{
return p->display();
}
Two things are obvious now:
The default argument can only possibly come from the default argument specified in base.
The actual dispatch is dynamic, since display is a virtual member function.
When you use -> i.e. invoke a function using a pointer it uses the object which is being pointed for taking a decision which in this case is an object of Derived class.
As the specification says...
A virtual function call uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.