Use the base-class virtual method - c++

Starting from this code:
class Base{
public:
virtual void foo(){....}
};
class Derived{
public:
void foo(){....}
};
If d is a Derived object, can I in some way invoke the foo method defined in the Base class for this object?
Edit: i mean from the outside, such that d.foo() binds to Base::foo()

Specify it explicitly in the call.
#include <iostream>
class Base{
public:
virtual void foo(){
std::cout << "Base" << std::endl;
}
};
class Derived : public Base{
public:
void foo(){
std::cout << "Derived" << std::endl;
}
};
int main()
{
Derived d;
d.Base::foo();
return 0;
}

Just qualify the call (Assuming that Derived actually inherits from Base, which in your code it doesn't):
Derived d;
d.Base::foo();
Now, while this is doable, it is also quite questionable. If the method is virtual, it is meant to be overridden and users should not call a particular override, but the final-overrider, or else they risk breaking class invariants all the way through.
Consider that the implementation of Derived::foo did some extra work needed to hold some invariant, if users call Base::foo that extra work would not be done and the invariant is broken, leaving the object in an invalid state.

To call it from outside code, you can still explicitly qualify the name in the call:
#include <iostream>
#include <vector>
struct base {
virtual void do_something() { std::cout << "Base::do_something();\n"; }
};
struct derived : public base {
virtual void do_something() { std::cout << "derived::do_something();\n"; }
};
int main() {
derived d;
d.base::do_something();
return 0;
}
If you're using a pointer to the object, you'd change that to d->base::do_something();.

Related

Redefined virtual function call

Consider:
#include <iostream>
class Base
{
public:
virtual void foo() { std::cout << "Base::foo()\n"; };
};
class Derived : public Base
{
public:
void foo() override
{
std::cout << "Derived::foo()\n";
Base::foo();
}
};
int main()
{
Derived obj;
obj.foo();
return 0;
}
This is my code. Why can I call Base::foo() in the Derived class if I already redefined it in Derived class. Why doesn't the compiler delete Base::foo in class Derived after redefine?
"why compiler doesn't delete Base::foo in class Derived after redefine"
Because that isn't what virtual and override do. When you provide an override to a base class function, you do not replace it. You are defining a new version for that function. The base class's implementation continues to exist and to be accessible.
Consider the following code. Someone can still use a Base object, and the behaviour should not be changed because Derived exists. The output for base_obj.foo() should continue to be "Base::foo()" regardless of the existance of Derived. :
#include <iostream>
class Base
{
public:
virtual void foo() { std::cout << "Base::foo()\n"; }
};
class Derived : public Base
{
public:
void foo() override { std::cout << "Derived::foo()\n"; }
};
int main()
{
Derived obj;
obj.foo();
Base base_obj;
base_obj.foo();
return 0;
}
Also consider that multiple classes can derive from Base. I could add a class MyClass : public Base with its own version of foo(), and it should not interfere with how Base or Derived objects behave.
If overriding a member function would cause the base member function to be entirely replaced or removed, it becomes nearly impossible to reason about code without reading carefully every class that derives from it. And unless your IDE provides tools for that, it implies reading all of the code base. It would make it C++ code that uses polymorphism extremely difficult to understand.

Virtual function behavior in derived classes

Can I have a virtual function in the base class and some of my derived classes do have that function and some don't have.
class A{
virtual void Dosomething();
};
class B : public A{
void Dosomething();
};
class C : public A{
//Does not have Dosomething() function.
};
From one of my c++ textbook:
Once a function is declared virtual, it remains virtual all the way down the inheritance, even if the function is not explicitly declared virtual when the derived class overrides it.
When the derived class chooses not to override it, it simply inherits its base class's virtual function.
Therefore to your question the answer is No. Class c will use Class A's virtual function.
Derived classes do not have to implement all the virtual functions, unless it is a pure virtual function. Even in this case, it will cause an error only when you try to instantiate the derived class( without implementing the pure virtual function ).
#include <iostream>
class A{
public :
virtual void foo() = 0;
};
class B: public A{
public :
void foo(){ std::cout << "foo" << std::endl;}
};
class C: public A{
void bar();
};
int main() {
//C temp; The compiler will complain only if this is initialized without
// implementing foo in the derived class C
return 0;
}
I think the closest you might get, is to change the access modifier in the derived class, as depicted below.
But, I would consider it bad practice, as it violates Liskov's substitution principle.
If you have a situation like this, you might need to reconsider your class design.
#include <iostream>
class A {
public:
virtual void doSomething() { std::cout << "A" << std::endl; }
};
class B : public A {
public:
void doSomething() override { std::cout << "B" << std::endl; };
};
class C : public A {
private:
void doSomething() override { std::cout << "C" << std::endl; };
};
int main(int argc, char **args) {
A a;
a.doSomething();
B b;
b.doSomething();
C c;
//c.doSomething(); // Not part of the public interface. Violates Liskov's substitution principle.
A* c2 = &c;
c2->doSomething(); // Still possible, even though it is private! But, C::doSomething() is called!
return 0;
}

Access another Base Classes member from Abstract Base Class

I wonder if it is possible to declare a pure virtual function in class AbstractBase and make a Base classes member visible in Derived so it will use the member of Base and not look for a implementation in Derived. So far, i tried making Base's member visual by trying to use using but it won't compile since the look up, in this case, seems to ignore using. Is this possible at all? Here is my code:
#include <iostream>
using namespace std;
class AbstractBase {
public:
AbstractBase(){}
virtual ~AbstractBase(){}
protected:
virtual void f() = 0;
};
class Base {
public:
Base(){}
protected:
void f() {cout << "called Base's f()" << endl;}
};
class Derived : public Base, public AbstractBase {
public:
Derived(){}
//using Base::f; /*this won't compile*/
private:
void f(){} /*Access Base's f() here rather than implement*/
};
int main()
{
Derived d;
}
Use :: operator:
class Derived : public Base {
public:
Derived(){}
private:
void f(){ Base::f() }
};
Also, you don't need to inherit from AbstractBase.
It looks to me that you would like f() to be pure-virtual but provide default implementation. In this case, it can be achieved this way:
#include <iostream>
using namespace std;
struct AbstractBaseWithDefaultF
{
virtual ~AbstractBaseWithDefaultF() = default;
virtual void f() = 0;
};
void AbstractBaseWithDefaultF::f()
{
cout << "called AbstractBaseWithDefaultF's f()" << endl;
}
struct Derived : AbstractBaseWithDefaultF
{
void f() override
{
AbstractBaseWithDefaultF::f();
cout << "called Derived's f()" << endl;
}
};
int main()
{
Derived d;
d.f();
}
Output:
called AbstractBaseWithDefaultF's f()
called Derived's f()
Here's a live Wandbox example.

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.