0

What is the derived class doing in this code like:

class Base
{
public:
       virtual std::string Name(){ return "Base Class"}

};
class Derived : public Base
{
 public:
        std::string Name() {return "Derived Class"}
}

int main()
{
   Base* object = new Derived();
   return 0;
}

I was following a tutorial but didn't understand What does Derived class in The instantiation of Base Class was doing in the above code.

2 Answers2

1

modifying main to be :

int main()
{
   Base* object = new Derived();

   std::cout << object->Name() << std::endl;
   return 0;
}

and adding 3 missing ';' in your code, you will see that writes Derived Class, the called method Name is the one of the real type of object being Derived.

Note while Name is virtual in Base it is also in Derived even you do not said explicitly.

virtual allows to use the real type of an object when you apply an method on, so even object is declared Base when Name is virtual the called version is the one of the real type being Derived


But if you remove virtual in the definition of Name in Base that writes Base Class because object being declared Base the called method is Name defined on Base.

The result will be the same adding virtual on Derived but still removing it on Base, because for the compiler object being declared Base and Name being not virtual on Base that one is called without considering the real type of object


So, having :

#include <iostream>
#include <string>

class Base
{
  public:
    virtual std::string virtualName(){ return "Base Class";}
    std::string nonVirtualName(){ return "Base Class";}
};

class Derived : public Base
{
 public:
   std::string virtualName() {return "Derived Class";} // implicitely virtual
   std::string nonVirtualName(){ return "Base Class";}
};

int main()
{
   Base* object = new Derived();

   std::cout << object->virtualName() << std::endl;
   std::cout << object->nonVirtualName() << std::endl;

   return 0;
}

Compilation and execution :

bruno@bruno-XPS-8300:/tmp$ g++ -Wall a.cc
bruno@bruno-XPS-8300:/tmp$ ./a.out
Derived Class
Base Class
bruno@bruno-XPS-8300:/tmp$ 

Note if you add delete object; at the end of main and because of the default destructor in not virtual the called destructor is the one of Base exactly for nonVirtualName and nothing is done for Derived. Defining the destructor virtual on Base is the right way to do, that implies the destructor is at least implicitly virtual on Derived allowing to have both destructors executed on delete object;

bruno
  • 32,421
  • 7
  • 25
  • 37
1

The goal is to implement polymorphism, it's a OOP concept which allows you, among other things, to make derived class methods override the base class.

Consider the following:

class Base {
public:
    //virtual keyword allows method to be overriden
    virtual std::string Name() { return "Base Class"; }
    //virtual destructor needed for polymorphism otherwise it can lead to undefined behavior
    virtual ~Base(){} 
};

class Derived : public Base {
public:
    //optional keyword override signal the method has been overriden
    std::string Name() override { return "Derived Class"; }
};

class Derived2 : public Base {
public:
    std::string Name() override { return "Derived Class 2"; }
};

int main() {

    Base *object = new Derived();
    Base *object2 = new Derived2();
    Base *object3 = new Base();
    //collection of objects of type Base* which can hold any class of the family
    Base *collection[] = {object, object2, object3};

    for (auto &obj : collection) {//test print
        std::cout << obj->Name() << std::endl;
    }
}

As the comments explain, I can have a collection of different objects of the same family and when you call Name() the method call will deppend on the object.

Output:

Derived Class
Derived Class 2
Base Class
anastaciu
  • 23,467
  • 7
  • 28
  • 53