-1

Consider the following code:

#include <iostream>
#include<string>
using namespace std;
 
class Base
{
public:
    virtual string print() const
    {
        return "This is Base class";
    }
};
 
class Derived : public Base
{
public:
    virtual string print() const
    {
        return "This is Derived class";
    }
};
 
void describe(Base p)
{
    cout << p.print() << endl;
}
 
int main()
{
    Base b;
    Derived d;
    describe(b);
    describe(d);
    return 0;
}

On executing this code, it gives the output as

This is Base class
This is Base class

I had couple of doubts in this program:

  1. The function print in class Base is a const member function, hence after inheritance, when we try to override the definition of print in Derived class, why doesn't the compiler give an error.

  2. In this program, how we can we pass a derived class object (d) to the function which expects an argument of data Type Base.

  3. Even if we could somehow pass the derived class object to the function, why does it print "This is Base class" instead of "This is Derived Class".

  4. Does implicit type-conversion take place when I pass a derived class object to function describe?

I had be grateful if someone could explain me the working of this code.

  • 1
    Does this answer your question? [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) – Johan Jun 29 '21 at 05:49
  • When you `void describe(Base p)` do this your all the derived object sliced to the its base class. – foragerDev Jun 29 '21 at 05:50
  • @Johan This link does explain some of the things, but it still fails to clarify how we could succeed in overriding the const member function in derived class – newprogrammer Jun 29 '21 at 05:51
  • 2
    `const` function does not mean you can not override it. It is the part of function signature. you can have multiple function with same name on the base of constness. – foragerDev Jun 29 '21 at 05:52
  • TL;DR: `void describe(const Base& p)`. – Evg Jun 29 '21 at 05:53
  • Perhaps what you're looking for is [the `final` specifier](https://en.cppreference.com/w/cpp/language/final)? – Some programmer dude Jun 29 '21 at 05:56

2 Answers2

1
  1. The function print in class Base is a const member function, hence after inheritance, when we try to override the definition of print in Derived class, why doesn't the compiler give an error.

There is no error because the program is well-formed. It is unclear why you bring up the detail that the member function is const. Constness of a member function has no effect on whether the function can be overridden. Did you assume that const means final?

  1. In this program, how we can we pass a derived class object (d) to the function which expects an argument of data Type Base.

Because that class Base is a public base of the Derived class, and thus the derived object is implicitly convertible to the base. The result of the conversion is a copy of the base class sub object. This is colloquially called "slicing".

  1. Even if we could somehow pass the derived class object to the function, why does it print "This is Base class" instead of "This is Derived Class".

Because there is no derived class object inside the function. There is a copy of the base.

  1. Does implicit type-conversion take place when I pass a derived class object to function describe?

Yes. When you pass an argument of a type that is different from the type of a non-reference parameter, there is always an implicit conversion.


Indirection is necessary for runtime polymorphism. Try the same using a reference to base as parameter and you'll see the overriding function called.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

Your first question is why it did not give you an error because your function is const. Const function does not prohibit you from overriding it. If you want your function to be not overridden by derived classes you can declare that function final.

virtual string print() const final;

Now this will not be overridable by any other derived class. As far as you are concerned about the const. You can Overload your function on the basis of constness. For example, you can have.

virtual string print() const; // Does not modify anything
virtual string print(); Can modify `this`

For the second question can pass the Derived class object to a function witch expect the Base class object. But It is only possible if it is via reference or via a pointer.

void describe(const Base& p);
void describe(Base* p);

For the third question as you passed via copy, so your derived class object is narrowed to Base class. Which essentially loss all the additional information other than its Base class.

The fourth question has the same answer as 3. This is fully functional code as you had expected to run.

    #include <iostream>
    #include<string>
    using namespace std;
 
    class Base
    { 
        public:
        virtual string print() const
        {
            return "This is Base class";
        }
    };
 
    class Derived : public Base
    {
    public:
        virtual string print() const override
        {
            return "This is Derived class";
        }
    };
 
    void describe(const Base& p)
    {
       cout << p.print() << endl;
    }
 
    int main()
    {
       Base b;
       Derived d;
       describe(b);
       describe(d);
       return 0;
    }

Here you can see I declared overridden function override to tell the compiler that this function is being overridden from its Base Class. Without this, it works as expected but it's like function hiding rather than overriding.

foragerDev
  • 1,307
  • 1
  • 9
  • 22