-1

I am new to c++ oops concept.I want to know what is meaning of "Animal d=Dog();" and How can I invoke the print function of Dog class using d.print().

 #include <iostream>  
using namespace std;  
class Animal   
{  
public:  
    string color = "Black";

    void print()
    {
        cout << "This is animal class" << endl;
    }
};   

class Dog : public Animal   
{    
public:  
    string color = "Grey"; 

    void print()
    {
       cout << "This is Dog class "<< endl;
    }
}; 

int main() 
{  
     Animal d = Dog();
    // Dog d;
    cout << d.color << endl;
    d.print();
    return 0;
}
Moia
  • 2,216
  • 1
  • 12
  • 34

4 Answers4

1

There are two problems in your code, both which should have been addressed by any good book or tutorial (and should have been brought up in class if you're in school).

The first is that for runtime polymorphism to work, you need to mark the polymorphic functions as virtual. As in virtual void print() { ... }. Note that the virtual specifier is only needed in the base class.

The second thing you kind of have in your title, that you need a reference to a base object. C++ differs between direct objects (which is what your variable d is) and references to an object (which are variables declared using the &). You can also use pointers, which is usually more common.

To fix the reference issue either do

Dog dog;
Animal& d = dog;  // Make d reference dog

Or use pointers

Animal* d = new Dog;  // Create a new Dog object on heap and make d point to it

Regarding your current

Animal d = Dog();

there are a few related thing you need to learn about.

The first is about object slicing; And the second is that while inheritance is an "is a" relationship, that relationship is only one way

The class Dog "is a" Animal, but Animal is not a Dog.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 2
    "*Note that the `virtual` specifier is only needed in the base class*" - true, however in C++11 and later, when a derived class overrides a `virtual` method, it should be marked as `override` so the compiler validates the method is overriden correctly. – Remy Lebeau Aug 06 '18 at 06:55
0

First problem with your code is virtual function definition in base class. Secondly, use pointer to refer your child class. See the code below:

 #include <iostream>  
using namespace std;  
class Animal   
  {  public:  
    string color = "Black";  
    virtual void print()
    {
        cout<<"This is animal class"<<endl;
    }
};   
class Dog: public Animal   
{    
 public:  
    string color = "Grey"; 
 void print()
 {
    cout<<"This is Dog class"<<endl;
 }
};  
int main() {  
     Animal *d= new Dog;
     d->print();
  return 0;

}
Saboor
  • 352
  • 1
  • 10
0

In order to have runtime polymorphism you need to use pointers and virtual functions.

  • The print function needs to be virtual in the base class: virtual void print() and be override in the derived class: void print() override.
  • You must create a pointer to the base class and assign it to a derived class object: Animal* d = new Dog(); so that you can access the methods from the derived class through the virtual table.
  • Now you will need to call the methods or access the variables of your object by dereferencing the pointer, such as d->print() and d->color;

Be also aware that you can print the value of the color variable of the animal class from d, but you cannot access the color variable of the derived class, since d is a pointer to the base class. Therefore, cout<<d->color<<endl will be

Black

.

FrankS101
  • 2,112
  • 6
  • 26
  • 40
0

As explained by previous answers, making print function in base class virtual and implementing the print function with same signature in the derived class allows you to achieve dynamic polymorphism. In other words based on the type of object animal pointer points, determines which print function is called. C++11 introduced a keyword called override which indicates that the function is overriding a virtual function of the base class. Following snippet shows implementation with override keyword.

#include <iostream>  

using namespace std;  

class Animal {

public:  
    string color = "Black";  
    virtual void print() {
        cout<<"This is animal class"<<endl;
    }
};

class Dog: public Animal {

public:  
    string color = "Grey"; 

    void print() override {
        cout<<"This is Dog class"<<endl;
}

};  
int main() {  
     Animal *d= new Dog;
     d->print();
  return 0;

}

Let's understand how the dynamic polymorphism works. When you declare a function as virtual function in the base class a virtual function table gets created which contains virtual function pointers. Class contains a VPTR a pointer to virtual function table (This increase the size of the Animal object by size of the pointer which is dependent on the pointer size) In your example, when you declare a Animal class print function as virtual. VPTR (pointer to virtual function table) becomes a member of Animal class. The corresponding virtual function table looks as follows

enter image description here

When you create child class by deriving Animal class, Since the base class contains a virtual function, A new virtual function table gets automatically created with VPTR as a member of the derived class. This virtual function table contains a pointer to a print function. If you don't override the print function in derived class function, pointer in the virtual function table points to base class print function, this illustrated with the following diagram.

enter image description here

When you call print function from base class pointer, function is searched in virtual function table of the class to which base class pointer points. In your case if the Animal class pointer points to Animal object print function is searched in Animal class virtual table, If it points to Dog class then searched in the Dog class virtual function table. This is how dynamic polymorphism is achieved. As you can see function needs searched in the virtual function table. This introduces run time overhead, however in static polymorphism this is not the case where function to be called is decided at the compile time.

yadhu
  • 1,253
  • 14
  • 25