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;