Thread: Polymophism

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    241

    Polymophism

    I'm sorry if I missed an article about it (was looking for one) on the site. May someone give me an overview of the basics?

  2. #2
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    a snippet of code speaks a thousand words... paste this into your compiler


    Code:
    #include <iostream>
    using namespace std;
    
    class duck {      // the "generic" duck class.
    public:
      virtual void duckFunction() = 0;  // the "generic" duck function
    };
    
    class swan : public duck {  // swan "inherits" or "derives" from duck
    public:
      void duckFunction(){ cout << "Swan"; }; 
    };
    
    class heron : public duck {
    public:
      void duckFunction(){ cout << "Heron"; };
    };
    
    class goose : public duck {
    public:
      void duckFunction(){ cout << "Goose"; };
    };
    
    int main()
    {
      duck* MyDuck = new swan;  // declares 'MyDuck' a pointer to a generic duck
                                // and creates a new Swan, pointed by MyDuck
    
      MyDuck->duckFunction();   // calls swan::duckFunction()
      delete MyDuck;            // bye bye swan!
      cin.get();
    }
    try changing "new swan" into "new heron" or "new goose" - but you can't create a "new duck" (In this example, duck is an abstract class.. but it doesn't have to be).

    You will see how duck* may behave like any of its' derived types... This is the essence of polymorphism.. the ability for an object to behave like another object.

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    Thanks man This will come handy

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The goal of run-time polymorphism is to create a bunch of code that can be extended without changing that original code. For example, you could make a function:
    Code:
    void TalkToDuck(const duck& theDuck)
    {
      cout << "What type of duck are you? ";
      duck.duckfunction();
    }
    Now, that function will always work on ducks. Any time you have an implementation for a new type of duck, you don't have to change that function because polymorphism allows it to work on any class derived from duck. From other code you can pass it a swan or heron or goose or whatever:
    Code:
    int main()
    {
      swan mySwan;
      TalkToDuck(mySwan);
      goose goldenGoose;
      TalkToDuck(goldenGoose);
    }

  5. #5
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    so you make your own class kindof

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Well, you make a lot of your own classes when you create the inheritance hierarchy. The code that uses the base class (in my example TalkToDuck) doesn't have to be a class, it can be simple functions. You can think of three different steps.

    Step 1, create the base class and define the interface for the class. In this case, that would be creating the duck class. You can also create some of the derived classes that you know you will need at this point.

    Step 2, create code that uses the base class by reference or pointer. In this case, that is creating the TalkToDuck function. That function uses duck's interface regardless of the actual derived class type.

    Step 3, which can be done over and over again, is add new derived classes that implement the base class interface from step 1. In this case, you would be creating the heron, swan, or goose class. You would then have to modify the code that creates objects since at that point you need to know which type of duck you are using. However, you don't have to touch TalkToDuck. In real world applications, you don't just have one function. You have a bunch of code that you created in Step 2 that never has to change as you extend your program to handle more types of ducks.

  7. #7
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    So this would be a decent template?
    EDIT: Better format
    Code:
    #include <iostream>
    #include "MyHeader.h"
    
    using namespace std;
    
    class First 
    	{
    	     public:
    	     virtual void MyFunc() = 0;
    	}
     
     
    class Second:
        public First
        {
        	public:
         	{ 
          		void MyFunc() 
            	{
            	        /*PUT STUFF HERE*********************
             	        *************************************
                            *************************************
                   	        ************************************/
              	};
         	}  	
        }        
    /* End of class */
    
    class Third:
        public First
        {
        	public:
    	{
       		void MyFunc()
        		{
                	        /**PUT DIFFRENT STUFF HERE THAT DOES*
                	        THE SAME THING***********************
                	        *************************************
                	        ************************************/
        	        };
         	}  	
       }
    /* End of class */
    
    
    class Fourth:
        public First
        {
        	public:
        	{
       		void MyFunc()
            	{
           			/*GUESS WHAT.... PUT MORE STUFF HERE*
            		**********   =O   ******************* 
                	        ***************ALWAYS FUN************
               		************************************/
           		};
       	} 		
        }
    /* End of class */
    
    
    int main()
    {
        First* MyFunction = /*dunno what to do here*/;
        MyFunction->MyFunc();
        delete /*???????*/;
        return 0;
    }
    Last edited by bikr692002; 03-21-2006 at 03:30 PM.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That is fine, although your actual programs won't look like that, at least not the main() part. You would replace /*???????*/ with MyFunction and /*dunno what to do here*/ with new Second or new Third depending on which derived class you wanted to create.

    Also, I wouldn't call the variable MyFunction, since it is a pointer to an instance of a class, not a function.

  9. #9
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    so
    Code:
    #include <iostream>
    #include "MyHeader.h"
    
    using namespace std;
    
    class First 
    {
    	public:
    	virtual void MyFunc() = 0;
    }
     
     
    class Second:
    public First
    {
    	public:
    	{ 
    		void MyFunc() 
    		{
    			/*PUT .......... HERE**********************
    			*************************************
    			*************************************
    			************************************/
    		};
    	}  	
    }        
    /* End of class */
    
    class Third:
    public First
    {
    	public:
    	{
    		void MyFunc()
    		{
    			/***PUT DIFFRENT .......... HERE THAT DOES*
    			THE SAME THING***********************
    			*************************************
    			************************************/
    		};
    	}  	
    }
    /* End of class */
    
    
    class Fourth:
    public First
    {
    	public:
    	{
    		void MyFunc()
    		{
    			/**GUESS WHAT.... PUT MORE .......... HERE*
    			**********   =O   ******************* 
    			***************ALWAYS FUN************
    			************************************/
    		};
    	} 		
    }
    /* End of class */
    
    
    int main()
    {
        First* MyClass = new Second;
        MyClass->MyFunc();
        delete MyClass;
        return 0;
    }
    Last edited by bikr692002; 03-21-2006 at 03:37 PM.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Yes that is a valid example template (other than some missing semi-colons). Obviously, you would need an actual scenario to really demonstrate the point of polymorphism instead of just the mechanics of it.

    Actually, I just realized an issue with both your example and Bench82's original duck example. Both cause undefined behavior because they use delete on the base class pointer. You need a virtual destructor in the base class:
    Code:
    ~First() { }
    I wouldn't recommend using new and delete in your example, as it complicates things. That's one of the reasons I used a function in my example.
    Last edited by Daved; 03-21-2006 at 03:42 PM.

  11. #11
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    Ok ok, I need to stop pasting code, last code (on this page) for me
    Code:
    #include <iostream>
    #include "MyHeader.h"
    
    using namespace std;
    
    class First 
    {
    	public:
    	virtual void MyFunc() = 0;
    };
     
     
    class Second:
    public First
    {
    	public:
    	{ 
    		void MyFunc() 
    		{
    			/*PUT S**T HERE**********************
    			*************************************
    			*************************************
    			************************************/
    		};
    	};
    };
    /* End of class */
    
    class Third:
    public First
    {
    	public:
    	{
    		void MyFunc()
    		{
    			/***PUT DIFFRENT S**T HERE THAT DOES*
    			THE SAME THING***********************
    			*************************************
    			************************************/
    		};
    	};	
    };
    /* End of class */
    
    
    class Fourth:
    public First
    {
    	public:
    	{
    		void MyFunc()
    		{
    			/**GUESS WHAT.... PUT MORE S**T HERE*
    			**********   =O   ******************* 
    			***************ALWAYS FUN************
    			************************************/
    		};
    	};	
    };
    /* End of class */
    
    
    int main()
    {
        First* MyClass = new Second;
        MyClass->MyFunc();
        delete MyClass;
        return 0;
    }
    This is right, no?

    EDIT:How does this get to Third and Fourth?

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Don't forget the virtual destructor (I edited my response). Then make sure it compiles and runs (even if it does nothing) and you will be fine.

  13. #13
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    hmm??? ~_~ Confused

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I think if you want to understand a complicated topic such as polymorphism you should read about it in your book or find keep looking for a good tutorial. Discussions like this should add to your more detailed study of the subject.

    If you're not familiar with new and delete, you might not be ready for polymorphism. If you are not familiar with the destructor, then you might not be ready for polymorphism. If you are just confused about the virtual destructor problem, then just accept it.

    As far as getting to Third and Fourth, that is the point. You would be changing the code in main() to use Second or Third or Fourth based on some input from a file or a user or something. In your simple example, you just decided to use Second. For example, you could ask the user and depending on the user input pick Third or Fourth instead.

  15. #15
    Registered User
    Join Date
    Sep 2005
    Posts
    241
    I almost have it, just one line messing me up
    Code:
    		char hello[25];
    		hello="Hello world, my friend.\n";
    It's saying "ISO C++ Forbids assignments of arrays"
    Should I do hello="Hello"+" "+"world,"+" "+"my"+" "+friend.\n"; ???? I know... it's a stupid idea

Popular pages Recent additions subscribe to a feed