Calling overridden child method from base method in c++ - c++

Here is the code:
#include <iostream>
class A
{
public:
void foo()
{
cout<<"this is base foo()"<<endl;
}
void callfoo()
{
foo();
}
};
class B: public A
{
public:
void foo()
{
cout<<"this is child foo()"<<endl;
}
};
int main()
{
B b;
b.callfoo(); //Output: "this is base foo()"
b.foo(); //Output: "this is child foo()"
return 0;
}
Now when I call b.callfoo(), instead of calling the foo() of child class B, callfoo() calls foo() of base class A. In class B we have overridden foo() with a new implementation, but still callfoo() is calling the base foo() instead of the child foo(). Please help if you have any explanation for this behaviour.

In C++, you need to explicitly mark methods as overridable by adding the virtual keyword: virtual void foo().

Related

Overriding non-virtual function from abstract grandparent class

I am learning and playing around with inheritance and abstract classes. I've run into a predicament that I would appreciate some clarifications on.
I am trying to override a non-virtual function from an abstract grandparent class. I am getting an error saying that 'member function declared with 'override' does not override a base class member.
I can call the original non-virtual function from child class instances in main(), but not override them in child classes?
Here's the code.
UPDATE:
Error went away when I marked the function as virtual, I would still appreciate an explanation as to why that virtual is necessary?
#include <iostream>
using namespace std;
class A
{
public:
virtual string GetClassName() = 0;
void foo(); // <--- this is the problem function
{
cout << "foo" << endl;
}
};
class B : public A
{
public:
string GetClassName() override
{
return "B";
}
};
class C1 : public B
{
public:
string GetClassName() override
{
return "C";
}
};
class C2 : public B
{
public:
void foo() override // ERROR:member function declared with override does not override a base class member.
{
cout << "foo c1" << endl;
}
};
// testing interface
void printName(A* ptr)
{
cout << ptr->GetClassName() << endl;
}
int main()
{
B* b = new B();
C1* c1 = new C1();
C2* c2 = new C2();
printName(b); // prints B
printName(c1); // prints C
printName(c2); // prints B
b->foo(); // prints foo, inherited directly from abstract class
c1->foo(); // prints foo, inherited directly from abstract class
c2->foo(); // ??
}
You cannot override a non-virtual function. It is as simple as that.
Methods in child classes can hide methods of parent classes when they have the same name, for example:
struct A {
void foo(){}
};
struct B : A {
void foo() {}
};
But thats not overriding. To override the method must be virtual. Thats one of the conditions that the override specifier helps to check:
struct A {
virtual void foo(){}
};
struct B : A {
void foo() override {} // <- error if A::foo is not virtual
};
PS: I have seen poor tutorials, that use the first example and call that overriding. Thats just wrong.

How does an inheritant class work in this situation ???

class A {
public:
A() { foo(); }
~A() { foo(); }
void foo() { cout << 3; }
void bar() { foo(); }
};
class B : public A {
void foo() { cout << 2; }
};
int main() {
B b;
b.bar();
return 0 ;
}
I compiled and ran it . The result is 333
... but I thought: when I call b.bar() . It would be directly to bar() and then call foo() function which is in class B because foo() in class A is overridden in class B . The result I thought is 323 . But I was wrong. Have I missed something ? Please help me to explain how it atually works #
THe problem is that you have a non virtual foo() so that A::bar() will call the only foo() it knows, being A::foo(), even if it's B that invokes it.
Try:
class A {
public:
A() { foo(); }
virtual ~A() { foo(); } // <<---------- recommendation
virtual void foo() { cout << 3; } // <<<--------- solves it
void bar() { foo(); }
};
class B : public A {
void foo() override { cout << 2; } // <<---------- recommendation
};
Additional infos:
Making foo() virtual in the base class allows each class to override this function, and be sure that the foo() that is invoked is will be the foo() corresponding to the object's real class.
It's a good practice then to use the keyword override in the derived classes: it's not mandatory, but in case you make a typo in the functions signature, you'll immediately notice with a compile-time error message.
Another good practice is to make your base class destructor virtual if you have at least one virtual function in the class.
A final remark: in B, foo()'s private. This is legal, but it's weird because the inheritance says that B is a kind of A, but you can't use B objects exactly as an A object.
Member A::foo is non-virtual and will therefore be statically bound wherever used. So when compiling A::bar, the call to foo() will be (statically) bound to the implementation A::foo(). This statical binding in A::foo will not be changed by the fact that you create an instance of derived class B later on.
If you call b.foo() in you main, however, B::foo will be bound.
In order to have B::foo to be called through A::bar, you'll have to declare A::foo as `virtual:
class A {
public:
A() { foo(); }
virtual ~A() { foo(); }
virtual void foo() { cout << 3; }
void bar() { foo(); }
};
Note that you'd also declare the destructor as virtual; non-virtual destructors do very rarely make sense.
You must include virtual in order to override the functionality stored in A.
Add to A
virtual void foo() { cout << 3; }
and to B
void foo() override { cout << 2; }
Should do the trick. Virtual functions are member functions whose behavior can be overridden in derived classes. As opposed to non-virtual functions, the overridden behavior is preserved even if there is no compile-time information about the actual type of the class. If a derived class is handled using pointer or reference to the base class, a call to an overridden virtual function would invoke the behavior defined in the derived class.

Why override under private inheritance?

class Base {
public:
virtual void f() {}
};
class Derived : private Base {
public:
void f() override {}
};
My question is there any use to such override? Private inheritance implies that you can not store Derived in Base pointer and thus it will never be needed to dynamically dispatch f to the correct type.
Just one example: A function of Derived::f1() can call a (public or protected) functions of Base::f2(), which in turn can call f(). In this case, dynamic dispatch is needed.
Here is an example code:
#include "iostream"
using namespace std;
class Base {
public:
virtual void f() {
cout << "Base::f() called.\n";
}
void f2() {
f(); // Here, a dynamic dispatch is done!
}
};
class Derived:private Base {
public:
void f() override {
cout << "Derived::f() called.\n";
}
void f1() {
Base::f2();
}
};
int main() {
Derived D;
D.f1();
Base B;
B.f2();
}
Output:
Derived::f() called
Base::f() called

Base class method alias

Let's consider the following code:
#include <iostream>
class Base
{
public:
void foo() //Here we have some method called foo.
{
std::cout << "Base::foo()\n";
}
};
class Derived : public Base
{
public:
void foo() //Here we override the Base::foo() with Derived::foo()
{
std::cout << "Derived::foo()\n";
}
};
int main()
{
Base *base1 = new Base;
Derived *der1 = new Derived;
base1->foo(); //Prints "Base::foo()"
der1->foo(); //Prints "Derived::foo()"
}
If I have the above stated classes, I can call the foo method from any of Base or Derived classes instances, depending on what ::foo() I need. But there is some kind of problem: what if I need the Derived class instance, but I do need to call the Base::foo() method from this instance?
The solve of this problem may be next:
I paste the next method to the class Derived
public:
void fooBase()
{
Base::foo();
}
and call Derived::fooBase() when I need Base::foo() method from Derived class instance.
The question is can I do this using using directive with something like this:
using Base::foo=fooBase; //I know this would not compile.
?
der1->Base::foo(); //Prints "Base::foo()"
You can call base class method using scope resolution to specify the function version and resolve the ambiguity which is useful when you don't want to use the default resolution.
Similar (Not exactly same case) example is mentioned # cppreference
struct B { virtual void foo(); };
struct D : B { void foo() override; };
int main()
{
D x;
B& b = x;
b.foo(); // calls D::foo (virtual dispatch)
b.B::foo(); // calls B::foo (static dispatch)
}

A virtual function that must be overridden

Consider a base class class Base which has a function virtual void foo(void). This function is implemented in Base; i.e. is not pure virtual.
Is there a pattern I can use which when inheriting from this class, i.e. class Child : public Base, compels me to override foo?
Other than making it a pure virtual function, there is no way to make the override required.
Note that the fact that a function is marked pure virtual does not mean that it cannot have an implementation in the base class - it means only that the derived class must override it.
struct Base {
virtual void foo() = 0; // foo() is pure virtual
};
struct Derived : public Base {
void foo() { // Derived overrides the pure virtual
cout << "Hello ";
Base::foo(); // Call the implementation in the base
cout << endl;
}
};
void Base::foo() {
cout << " world";
}
int main() {
Derived d;
d.foo();
return 0;
}
This prints "Hello world", with the "world" part coming from the implementation in the base class.
Demo.
C++11 introduced the override keyword to help with this:
struct Base
{
void foo();
};
struct Derived : Base
{
void foo() override; // error! Base::foo is not virtual
};
However you can not write this in Base itself to get the same effect; i.e. there is no mustoverride specifier. Ultimately, it is none of Base's business as to what derived classes do or don't override.
You can keep Base abstract whilst providing a "default" definition for your pure virtual functions:
struct Base
{
virtual void foo() = 0;
};
void Base::foo() {}
struct Derived : Base {}; // error! does not override Base::foo
struct Derived2: Base
{
virtual void foo() override
{
Base::foo(); // invokes "default" definition
}
};
This will be an acceptable solution if you are content for the entire base type to be rendered uninstantiable.
A pure-virtual member function can still have a body. The only caveat is that it must be defined outside the class definition. This is perfectly legal C++:
#include <iostream>
struct Base
{
virtual void foo() const = 0;
};
void Base::foo() const
{
std::cout << "Base!\n";
}
struct Derived : Base
{
// Uncomment following line to remove error:
//virtual void foo() const override { std::cout << "Derived\n"; Base::foo(); }
};
int main()
{
Derived d;
d.foo();
}
Live example
Notice that this makes Base an abstract class in all respects, i.e. it's impossible to instantiate Base directly.
Yes, actually there is:
#include <iostream>
class Base
{
public:
virtual void someFun() {std::cout << "Base::fun" << std::endl;}
virtual ~Base() {}
};
class AlmostBase : public Base
{
public:
virtual void someFun() = 0;
};
class Derived : public AlmostBase
{
public:
virtual void someFun() {std::cout << "Derived::fun" << std::endl;}
};
int main()
{
Derived *d = new Derived();
d->someFun();
delete d;
}
If you uncomment the someFun from Derived the compiler will complain ...
You introduce an intermediary class AlmostBase which has the function as pure virtual. This way you can have Base objects too, and the only drawback now is that all your classes will need to inherit from the intermediary base.
you can make the base method throw an exception when called, then the class must override it to avoid the parent execution.
this is used in the MFC FrameWork for example
// Derived class is responsible for implementing these handlers
// for owner/self draw controls (except for the optional DeleteItem)
void CComboBox::DrawItem(LPDRAWITEMSTRUCT)
{ ASSERT(FALSE); }
void CComboBox::MeasureItem(LPMEASUREITEMSTRUCT)
{ ASSERT(FALSE); }
int CComboBox::CompareItem(LPCOMPAREITEMSTRUCT)
{ ASSERT(FALSE); return 0; }
those methods must be inherited if the control is owner drawn it is responsible for the measuer, draw,... if you missed it while you are testing the function you will get an assert or exception with useful information thrown.