0

I was studying OOP from here.

It says that runtime polymorphism is possible in C++ using data members.

Now,consider this code:-

#include <iostream>    
using namespace std;    
class Animal {                                 //  base class declaration.  
    public:    
    string color = "Black";      
};     
class Dog: public Animal                       // inheriting Animal class.  
{      
    public:    
    string color = "Grey";      
};    
int main(void) {    
     Animal d= Dog(); 
     Animal d1 = Animal();     
     cout<<d.color<<endl;
     cout<<d1.color<<endl;    
}    

In both the cases above the color "black" is printed. So, how is this example of runtime polymorphism ?

Jason
  • 36,170
  • 5
  • 26
  • 60
coder_01
  • 83
  • 3
  • 2
    Define better runtime polymorphism. You could consider generating code on the fly using [asmjit](https://github.com/asmjit). You certainly need `virtual` methods and should be aware of the [C++ rule of five](https://cpppatterns.com/patterns/rule-of-five.html) – Basile Starynkevitch Jun 25 '22 at 07:33
  • 2
    You may want to use [C++ lambda functions](https://en.cppreference.com/w/cpp/language/lambda) and [std::function](https://en.cppreference.com/w/cpp/utility/functional/function). On Linux you might use [dlopen(3)](https://man7.org/linux/man-pages/man3/dlsym.3.html) with [dlsym(3)](https://man7.org/linux/man-pages/man3/dlsym.3.html) – Basile Starynkevitch Jun 25 '22 at 07:38
  • 2
    Worth a read: [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) You most likely don't want to redefine the `color` member in the derived class either. That tutorial is pretty bad IMO, even the example shown gives the base class output with no explanation of why. – Retired Ninja Jun 25 '22 at 07:41
  • 2
    The example given is incorrect. It says: "Let's see an example where we are accessing the field by reference variable which refers to the instance of derived class," but there are no reference variables in that example. Looks like a Java programmer tries to teach others how to program in C++. – Dmitry Kuzminov Jun 25 '22 at 07:47
  • 2
    Wow, so bad. There are lots of traps for the Java programmer learning C++. To have a tutorial which makes basic mistakes doesn't make things easier. – john Jun 25 '22 at 07:52
  • Quite apart from the errors in the tutorial, it's clear from your code above that you haven't understood how polymorphism works in C++. Suggest you look for a better tutorial. – john Jun 25 '22 at 07:59

2 Answers2

3

how is this example of runtime polymorphism ?

It is not an example of runtime polymorphism but rather of object slicing.

This is one of the reason why a good C++ book is recommended over online sites like this.

That is, the first choice/preference should always be(assuming you want to have a deep understanding of the subject) a good book. And then only, after you've read up the topic in the book you can look it up on sites for practical examples of the same. If you want to refer to legit C++ documentation sites you can refer to cppreference and learncpp. These two sites are C++ dedicated sites so you can rely on most of the info/example given there. Again referring to a book first is recommended.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 1
    So, runtime polymorphism is not possible using data members in C++, right ? – coder_01 Jun 25 '22 at 07:54
  • 2
    @coder_01 One of the few sites that are actually technically correct in documenting C++ is [learncpp](https://www.learncpp.com/cpp-tutorial/virtual-functions/) and from there: *"A virtual function is a special type of function that, when called, resolves to the most-derived version of the function that exists between the base and derived class.This capability is known as polymorphism."*.So since your class don't have any virtual function there is no runtime polymorphism.Also note the first choice should always be a book and then only one should move to an online site for seeing some examples. – Jason Jun 25 '22 at 07:59
  • 2
    @coder_01 Even without object slicing you can only refer to `Animal::color` given an instance of `Animal` or a reference to one. Accessing `Dog::color` requires an expression of type `Dog`, a subclass of `Dog` not providing its own `color` member variable or a reference to one of those. `Animal&& d = Dog(); std::cout << d.color << '\n' << static_cast(d).color << '\n';` prints `"Black"` as first line, even though `d` refers to a `Dog`. – fabian Jun 25 '22 at 08:09
2

If this was runtime polymorphism you could write a function:

void foo(Animal& a) {
    std::cout << a.color << "\n";
}

And it would print the respective color of the object based on the dynamic type of the parameter. However, there is no such thing as "Runtime-polymorphism based on member variables" in C++. The tutorial is wrong and misleading.

If compile and execute this:

#include <iostream>    
using namespace std;    
class Animal {                                          //  base class declaration.  
    public:    
    string color = "Black"; 
};     
class Dog: public Animal                       // inheriting Animal class.  
{      
    public:    
    string color = "Grey";      

}; 

void foo(Animal& a) {
    std::cout << a.color << "\n";
}
int main(void) {    
     Dog d= Dog(); 
     Animal d1 = Animal();     
     foo(d);
     foo(d1);
} 

The output will be

Black
Black

There is no such thing as virtual member variables. Only for virtual member functions use virtual dispatch:

#include <iostream>    
using namespace std;    
class Animal {                                          //  base class declaration.  
    public:    
    virtual std::string color() const { return "Black"; }
};     
class Dog: public Animal                       // inheriting Animal class.  
{      
    public:    
    std::string color() const override { return "Grey"; }

}; 

void foo(Animal& a) {
    std::cout << a.color() << "\n";
}
int main(void) {    
     Dog d= Dog(); 
     Animal d1 = Animal();     
     foo(d);
     foo(d1);
}  

Output:

Grey
Black

The turial is wrong and misleading when it says that there would be runtime polymorphis with member variables. Moreover the example they present has object slicing. See here: What is object slicing?.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185