0

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gevv
  • 25
  • 7
  • "why I can call Base::foo() in Derived class" - Ehh, because that's the way C++ works... May I suggest you pick up [a few good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and actually learn the language (btw; that'll take a few (3-5) years). – Jesper Juhl Nov 02 '22 at 18:43
  • Calling it like this `Base::foo()`, the member function call does not use the dynamic dispatch mechanism. – Eljay Nov 02 '22 at 18:43
  • Your title gives you away - you say "redefine". Nothing is redefined, both functions still exist, and are available in various different contexts just like you've seen. – Mike Vine Nov 02 '22 at 18:47
  • One issue is that there may be a child or derived class that needs the `Base::foo()` class. Since there is only one copy of `Base` methods, you are not really saving much by deleting the `Base::foo()` method. – Thomas Matthews Nov 02 '22 at 19:43

1 Answers1

2

"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.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
  • But I didn't understand after overriding foo() in Derived class, does Derived contain foo() function with Base::foo() implementation or not? – Gevv Nov 02 '22 at 18:56
  • @Gevv `Derive` publicly inherits from `Base`. So a `Derive` can be used to call any `Base` member functions if you ask nicely. If you write `obj.Base::foo();` then it will call the `Base` version of the function, since you are asking for it explicitly. Note that class objects do not "contain" any functions. Functions don't increase an object's size, objects don't store functions are part of their memory representations. Functions are not objects, they just describe a behavior. They exist statically separate from objects. – François Andrieux Nov 02 '22 at 19:01
  • By saying Derived I mean Derived class not Derived object – Gevv Nov 02 '22 at 19:03
  • Then yes, `Derived` provides every `public` member function that `Base` does. This includes version of a function that the derived type overrides. Overriding allows you to define a new version of the base function and changes which is called by default when the function name is unqualified. But the base version is still accessible. But in practice, it is rare that anyone would ever choose to explicitly call the base version of a `virtual` member function. – François Andrieux Nov 02 '22 at 19:05