Call a Overloaded Function of Inherited Class from Base Class - c++

#include<iostream>
class A {
public:
void init(){
std::cout << "A" << std::endl;
}
};
class B: public A {
public:
void init(){
std::cout << "B" << std::endl;
}
};
int main() {
A *o = new B();
/*
Some codes here
*/
o->init();
return 0;
}
Result:
A
In the above program, the init called is of class A. How do I call the init function of class B?
edit: I need to call both the inits. I can't change the A and B class. And I have to make the object declaration like that in main.

Make the init() function virtual in Class A.
class A {
public:
virtual void init(){
std::cout << "A" << std::endl;
}
};
The object o has two parts. The base part and the derived part. If you want B::init() to be called from o, then you will have to tell the compiler that it is a virtual function and it should look for the function overload in the derived class.
I suggest you go through the tutorial on this website to learn more about inheritance:
http://www.learncpp.com/cpp-tutorial/113-order-of-construction-of-derived-classes/

You have some options here:
B *o = new B(); // in Main
or
(B *)o->init(); // in Main
or
virtual void init(){
std::cout << "A" << std::endl;
} // in Class A

b = dynamic_cast<B*>(o);
if(b!=NULL)
b->init();
this will call the function for object of type B.

make init function virtual
create a pointer of class A
create an object of class B
assign address of B object to pointer A
now access init function of B

since class B hides the definition of init() in its base-class, it will make the function sensitive to the type of any pointer or reference from which the function might be called.
And as you mentioned A and B are prewritten class, you can instantiate a pointer to class B, or cast to a pointer to class B.

Related

How to call class A's method 1 which invokes class B's method 2 in C++?

I have a base class A and hope to create a class B with very similar functionality. I want class B to have a function to call class A's func1(), but when calling it, the func2() is replaced/over-rided by class B's func2(). My goal is to avoid repeated code and not modify class A. The inheritance implementation below does not work. Should I use inheritance here? How can I achieve my goal?
#include <iostream>
using namespace std;
class A {
public:
void func1() {
func2();
cout << "class A fun1" << endl;
}
private:
void func2() {
cout << "class A fun2" << endl;
}
};
class B : A{
public:
void func3() {
func1();
cout << "class B fun3" << endl;
}
private:
void func2() {
cout << "class B fun2" << endl;
}
};
int main() {
B b;
b.func3();
return 0;
}
The current output is:
class A fun2
class A fun1
class B fun3
But what I want is:
class B fun2
class A fun1
class B fun3
You should use virtual function for that. When a function is declared as virtual, the compiler only uses the implementation of the virtual function that is present in the derived class.
The function in the base class cannot be used directly from the base class. As in, if you create an object for the class A, you won’t be able to call func2() if it’s declared as virtual.
Note: You'll be able to call the virtual function from the derived class even though the virtual function definition is not present in the derived class (because it'll anyways be inherited and you'll be calling the inherited copy of the virtual function).
Hope it helps. Happy coding! :)

Accessing virtual base class function from a derived class

1.In the main function below, why does d.foo(9.5) not select the Base::foo(double) method from the base class? Doesn't the derived class inherit that method?
2.What causes the compile error?
class Base {
public:
virtual void foo(int){
cout << "Base::foo(int)" << endl;
}
virtual void foo(double){
cout << "Base::foo(double)" << endl;
}
};
class Derived : public Base {
public:
virtual void foo(int){
cout << "Derived::foo(int)" << endl;
}
};
void main() {
Derived d;
Base b, *pb = &d;
d.foo(9); // selects Derived::foo(int)
d.foo(9.5); // selects Derived::foo(int)
pb->foo(9); // selects Derived::foo(int)
pb->foo(9.5); // selects Base::foo(double)
Derived * d;
d->foo(9); // compile error
}
The compilation error is because of two variables with the same name in main().
As to your problem with inherited functions not being called for an instance of your Derived (except via pointer to Base)
The standard describes the "hiding rule", which makes this happen. Essentially, member functions declared in derived classes hide inherited functions with the same name but different signature inherited from the base class. The hiding rule is independent of whether the inherited functions are virtual or not.
The common solution is to introduce all inherited functions from the base class with using Base::foo. For example,
class Base {
public:
virtual void foo(int){
cout << "Base::foo(int)" << endl;
}
virtual void foo(double){
cout << "Base::foo(double)" << endl;
}
};
class Derived : public Base {
public:
using Base::foo;
virtual void foo(int){
cout << "Derived::foo(int)" << endl;
}
};
Another solution is to remember to explicitly override all inherited versions of the function (implement the derived class version to simply call the base class version of each function). This works with older compilers that do not support a using directive like the above. The catch is that it is necessary to explicitly do this with every inherited overload, and it is easy to miss one.
In the main function below, why does d.foo(9.5) not select the Base::foo(double) method from the base class? Doesn't the derived class inherit that method?
Yes, but it's hidden by the function with the same name in the derived class. You can unhide it with a using-declaration in the derived class:
using Base::foo;
What causes the compile error?
You're trying to declare a second variable called d. Change the name to something that's not already used; and initialise it to point to a valid object, otherwise you'll have a runtime error or other undefined behaviour.
Derived * pd = &d;
pd->foo(9); // selects Derived::foo(int)
Also, main has the wrong return type. It must return int.
1) Because this is exactly how polymorphism work. If a virtual function is redefined in a derived class, this (and only this) redefined version will be called. If the function is not virtual it's vice versa: only the base class function will be called.
//Example 1: non-virtual function
class Base
{
public:
void foo()
{
std::cout << "Base";
}
}
class Derived : public Base
{
public:
void foo()
{
std::cout << "Derived";
}
}
Base * base = new Base();
base->foo()//prints "Base"
Base * derived = new Derived();
derived->foo()//prints "Base", since the function is not virtual, and the version from the base class is called
//Example 2: virtual function
class Base
{
public:
virtual void foo()
{
std::cout << "Base";
}
}
class Derived : public Base
{
public:
void foo()
{
std::cout << "Derived";
}
}
Base * base = new Base();
base->foo()//prints "Base"
Base * derived = new Derived();
derived->foo()//prints "Derived", since the function is virtual, and the redefined version from Derived class is called
2) The compile error happens because you have a conflicting declaration - two objects are called d.
Derived * d;
d->foo(9); // compile error
You don't have instantiated the object:
Derived * d = new Derived;
If you not create the object the compiler use the previous declaration of d: Derived d that is not a pointer.

C++ Taking the Base Class as an Input and Accessing Derived Class Member Functions

Say I have defined 2 classes, a base class and a derived class. Then I write a function that takes the base class as an input.
When I use that function I will only ever pass in derived class functions and want to be able to access a redefined version of a base class method.
So lets say both the base and derived class have a method foo(). I create a derived class variable and pass it into a function that only accepts base class variables. Inside that function I want to access foo() as it is defined in the derived class, not as it is defined in the base class.
I have tried protected but that doesn't work.
Make the function virtual and that will access the derived class implementation on a base class pointer if the pointer points to a derived class instance.
Make sure you are passing a pointer or a reference (NOT passing the object by value)
class BaseT
{
public: virtual void f(string msg) { cout << msg << " from Base" << endl; }
};
class DerivedT: public BaseT
{
public: void f(string msg) { cout << msg << " from Derived" << endl; }
};
// myFunc says hi from derived or from base
// depending on what b really points to
void myFunc (BaseT *b) { b->f("hi"); }
int main(int argc, char* argv[])
{
DerivedT d;
BaseT b;
myFunc (&d);
myFunc (&b);
return 0;
}

Strange behavior with virtual functions

With the following code, I would expect output to be B.f B.f DD.f, but instead the output I get is B.f B.f B.f. How is that possible, when DD derives from D which has f as virtual.
class B
{
public:
void f() { cout << "B.f "; }
};
class D : public B
{
public:
virtual void f() { cout << "D.f "; }
};
class DD : public D{
public:
virtual void f() { cout << "DD.f "; }
};
B * b = new B();
B * d = new D();
B * dd = new DD();
b->f();
d->f();
dd->f();
Functions become virtual from the level they were declared virtual up. You first declare f virtual in D, which means the dynamic dispatch will only happen from D upwards. B doesn't, nor should it know about the deriving classes.
Think about how the compiler sees it:
You have a pointer to B - B has the following definition:
class B
{
public:
void f() { cout << "B.f "; }
};
Since f is not virtual, I'll just go ahead and resolve the call statically - i.e. B::f().
For dynamic dispatch to work from a pointer to B, you need to make f() virtual in B:
class B
{
public:
virtual void f() { cout << "B.f "; }
};
You need to set B::f() to virtual, without set B::f() to virtual, it won't appear in B virtual table(vtbl), thus B::f() is called instead of dispatch the call to derived class.
class B
{
public:
virtual void f() { cout << "B.f "; }
};
As soon as you declare f() virtual in B,this starts to maintain a virtual table that holds the function pointers of all the other functions of same name of derived classes. This is a lookup table that is used to resolve function calls in a dynamic/late binding manner.
When you use a reference or a pointer to call a method, the compiler searches in the type of the pointer or reference at the declaration of the method (here it searches in B the declaration of some method with signature f()). When it finds one :
if it is NOT marked as virtual, then it solves it as a call to the method defined for this class - this is a static binding.
if it is marked as virtual, then the method called will be the appropriate one of the object referenced or pointed by - this is a dynamic binding.
The next test would have been :
DD * dd = new DD();
D * d = dd;
B * b = d;
b->f();
d->f();
dd->f();
One single object new DD() that is used/viewed differently... Each type can be thought as a kind of view you have on an object. If you see it as a B then f() does something but always the same thing, but if you see it as D or DD, f() does something different...
If you meet someone in the street, the standard way for him to salute you is to say hello, but for the same person, when he meets a friend of him he can either say hi! or Yo! :
class Person {
public:
void salute() { cout << "Hello" << endl; }
};
class Friend : public Person {
public:
virtual void salute() { cout << "Hi!" << endl; }
};
class RoomMate : public Friend {
public:
virtual void salute() { cout << "Yo!" << endl; }
};
void asACustomer(Person &p) {
p.salute(); // static binding, we need the standard politeness
}
void asAFriend(Friend &f) {
p.salute(); // dynamic binding, we want an appropriate message...
}
RoomMate joe;
asCustomer(joe);
asFriend(joe);
With static binding you know at compile time which method is called; with dynamic binding you cannot, you only know that an appropriate one will be. This is a key point in sub-typing polymorphism.
In general, be careful when mixing static and dynamic binding for a method.

Can i use a method overriding a non-virtual method?

I am trying to understand a point here in C++.
If class A has a non-virtual method, and class B, which extends A, overrides that method, can i create an instance of B and somehow use the method defined in B?
Is there a point to override a non-virtual method?
Is there a point to override a non-virtual method?
You are not actually overriding, but this is the behavior, i.e
B* b = new B();
A* a = new B();
b->method(); //Calls B's method
a->method(); // Calls A's method
So, the pointer/reference type determines the method called.
can i create an instance of B and somehow use the method defined in B?
Yes. The pointer/reference type has to be of type B. (see previous example).
If you don't declare method to be virtual, you cannot override it, but you can hide it.
If B inherits from A, and redefines a method defined in A, then new instances of B will call B's version. However, if the method is not virtual, then there is no polymorphic behavior, so if an instance of B is referenced as an A, then the method will be A's. For example:
struct A {
void foo () { std::cout << "A::foo" << std::endl; }
};
struct B : public A {
void foo () { std::cout << "B::foo" << std::endl; }
};
B b;
b.foo();
A *a = &b;
a->foo();
The output of the code above would be:
B::foo
A::foo
However, if the foo method had been virtual, then B::foo would have been printed twice.
If a function is not virtual then the type of the variable determines which implementation is dispatched too:
#include <iostream>
using namespace std;
struct A {
void f() { cout << "A" << endl; }
};
struct B : public A {
void f() { cout << "B" << endl; }
};
int main(int args, char** argv) {
B b;
A& a = b;
b.f();
a.f();
return 0;
}
No, there is no mechanism to override a non-virtual method in class A.
Yes, you can use a non-virtual method from class A overloaded in B by using scope resolution operator A::methodName