Thread: Polymorphism Help

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    17

    Polymorphism Help

    I have a base class tree. Using this class, I have to create two derived classes, oak and pine.

    Here is the base class tree:
    Code:
    #ifndef TREE_H
    #define TREE_H
    
    //Tree class declaration
    
    #include<iostream>
    using namespace std;
    
    #define dead 0
    #define live 1
    #define burning 2
    #define newt 3
    
    class tree
    {
      protected:
        string type;
        double probCatch;
        int status;
        double wetness;
        int burnTime;
    
      public:
        tree();  //default constructor
        tree(string t, double prob, int stat, double wet, int burn); //constructor
        double getProbCatch() const; //accessor
        void setProbCatch(double prob); //mutator
        int getStatus() const;
        void setStatus(int stat);
        double getWetness() const;
        void setWetness(double wet);
        int getBurnTime() const;
        void setBurnTime(int burn);
        ostream& showSymbol(ostream& out);
    
      friend ostream& operator<<(ostream& out, tree&  a);
    };
    #endif //TREE_H
    Code:
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <cstdlib>
    #include "tree.h"
    #include "oak.h"
    #include "pine.h"
    using namespace std;
    
    
    //-------------------------------------------------------------------------
    //Default Tree Constructor
    //-------------------------------------------------------------------------
    
    tree::tree(): type("not_a_tree"), probCatch(0), status(dead), wetness(1), burnTime(1)
    {
      //empty body; initialization
    }
    
    //-------------------------------------------------------------------------
    //Tree Constructor
    //-------------------------------------------------------------------------
    
    tree::tree(string t, double prob, int stat, double wet, int burn): type(t), probCatch(prob), status(stat), wetness(wet), burnTime(burn)
    {
       //empty body; intialization
    }
    
    //-------------------------------------------------------------------------
    //Fetching Probability
    //-------------------------------------------------------------------------
    
    double tree::getProbCatch() const
    {
       return probCatch;
    }
    
    //-------------------------------------------------------------------------
    //Setting Probability
    //-------------------------------------------------------------------------
    
    void tree::setProbCatch(double prob)
    {
       probCatch=prob;
    }
    
    //-------------------------------------------------------------------------
    //Fetching Status
    //-------------------------------------------------------------------------
    
    int tree::getStatus() const
    {
      return status;
    }
    
    //-------------------------------------------------------------------------
    //Setting Status
    //-------------------------------------------------------------------------
    
    void tree::setStatus(int stat)
    {
       status=stat;
    }
    
    //-------------------------------------------------------------------------
    //Fetching Wetness
    //-------------------------------------------------------------------------
    
    double tree::getWetness() const
    {
      return wetness;
    }
    
    //-------------------------------------------------------------------------
    //Setting Wetness
    //-------------------------------------------------------------------------
    
    void tree::setWetness(double wet)
    {
       wetness=wet;
    }
    
    //-------------------------------------------------------------------------
    //Fetching Burn Time
    //-------------------------------------------------------------------------
    
    int tree::getBurnTime() const
    {
       return burnTime;
    }
    
    //-------------------------------------------------------------------------
    //Setting Burn Time
    //-------------------------------------------------------------------------
    
    void tree::setBurnTime(int burn)
    {
       burnTime=burn;
    }
    
    //-------------------------------------------------------------------------
    //Overloading Output <<
    //-------------------------------------------------------------------------
    
    ostream& operator<<(ostream& out, tree&  a)
    {
       out << "Species: "<< a.type <<endl;
       out << "Probability: "<< a.probCatch <<endl;
       out << "Status: "<< a.status <<endl;
       out << "Wetness: "<< a.wetness <<endl;
       out << "Burn time: "<< a.burnTime <<endl;
    
      return out;
    }
    
    //-------------------------------------------------------------------------
    //Show Symbols
    //-------------------------------------------------------------------------
    
    ostream& tree::showSymbol(ostream& out)
    {
      out<<"\033[32;40m!"<<endl;
     
     return out;
    }
    Here is the oak class:
    Code:
    //Oak class declaration
    
    #include "tree.h"
    #include<iostream>
    using namespace std;
    
    #define dead 0
    #define live 1
    #define burning 2
    #define newt 3
    
    class oak : public tree
    {
      public:
        oak();  //default constructor
        oak(string t, double prob, int stat, double wet, int burn); //constructor
        ostream& showSymbol(ostream& out);
    
      friend ostream& operator<<(ostream& out, tree&  a);
    };
    Code:
    #include <string>
    #include <cstdlib>
    #include "oak.h"
    #include "tree.h"
    using namespace std;
    
    
    //-------------------------------------------------------------------------
    //Default Tree Constructor
    //-------------------------------------------------------------------------
    
    oak::oak(): type("not_a_tree"), probCatch(0), status(dead), wetness(1), burnTime(1)
    {
      //empty body; initialization
    }
    
    //-------------------------------------------------------------------------
    //Tree Constructor
    //-------------------------------------------------------------------------
    
    oak::oak(string t, double prob, int stat, double wet, int burn): type(t), probCatch(prob), status(stat), wetness(wet), burnTime(burn)
    {
       //empty body; intialization
    }
    
    //-------------------------------------------------------------------------
    //Show Symbols
    //-------------------------------------------------------------------------
    
    ostream& oak::showSymbol(ostream& out)
    {
      out<<"\033[32;40m@"<<endl;
     
     return out;
    }
    The pine class is the same as the oak class except for the symbol.

    I'm getting the following errors when it compiles:
    Code:
    oak.cpp: In constructor ‘oak::oak()’:
    oak.cpp:14: error: class ‘oak’ does not have any field named ‘type’
    oak.cpp:14: error: class ‘oak’ does not have any field named ‘probCatch’
    oak.cpp:14: error: class ‘oak’ does not have any field named ‘status’
    oak.cpp:14: error: class ‘oak’ does not have any field named ‘wetness’
    oak.cpp:14: error: class ‘oak’ does not have any field named ‘burnTime’
    oak.cpp: In constructor ‘oak::oak(std::string, double, int, double, int)’:
    oak.cpp:23: error: class ‘oak’ does not have any field named ‘type’
    oak.cpp:23: error: class ‘oak’ does not have any field named ‘probCatch’
    oak.cpp:23: error: class ‘oak’ does not have any field named ‘status’
    oak.cpp:23: error: class ‘oak’ does not have any field named ‘wetness’
    oak.cpp:23: error: class ‘oak’ does not have any field named ‘burnTime’
    pine.cpp: In constructor ‘pine::pine()’:
    pine.cpp:13: error: class ‘pine’ does not have any field named ‘type’
    pine.cpp:13: error: class ‘pine’ does not have any field named ‘probCatch’
    pine.cpp:13: error: class ‘pine’ does not have any field named ‘status’
    pine.cpp:13: error: class ‘pine’ does not have any field named ‘wetness’
    pine.cpp:13: error: class ‘pine’ does not have any field named ‘burnTime’
    pine.cpp: In constructor ‘pine::pine(std::string, double, int, double, int)’:
    pine.cpp:22: error: class ‘pine’ does not have any field named ‘type’
    pine.cpp:22: error: class ‘pine’ does not have any field named ‘probCatch’
    pine.cpp:22: error: class ‘pine’ does not have any field named ‘status’
    pine.cpp:22: error: class ‘pine’ does not have any field named ‘wetness’
    pine.cpp:22: error: class ‘pine’ does not have any field named ‘burnTime’
    This is my first time doing polymorhpism and I'm not sure how to do it. I'm making some mistakes that are messing up the program and I can't catch them. Please help me if you can.

  2. #2
    Registered User
    Join Date
    May 2008
    Posts
    17
    Ok, according to the instructions, I have to create a base class pointer named treePtr that points to a tree object. Then that in turn will assign the address of each object to treePtr and call showSymbol() using:
    Code:
    (*treePtr).showSymbol(cout);
    or
    Code:
    treePtr->showSymbol(cout);
    I haven't done pointers before either. Can someone help me with creating one or give me links to sites that may help.

    Thanks a bunch!
    Ryan

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    What book are you using? I didn't read very much of the post, just the title and the fact that your base class doesn't have any virtual functions.

    I think you need a good C++ book.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is not with an attempt to use polymorphism per se. The problem is that type, probCatch, status, wetness and burnTime are member variables from the base class (tree), so they cannot be initialised in the derived class (oak). You can assign to them in the body of the constructor since they are declared protected, but it would be more efficient to invoke the base class constructor from the initialisation list of the derived class constructor:
    Code:
    oak::oak(): tree("not_a_tree", 0, dead, 1.0, 1)
    {
      //empty body; initialization
    }
    This would still work even if those member variables were private (and I find it better to make them private).

    However, you do have an issue where polymorphism is concerned: namely, your base class has no virtual member functions (in particular, its destructor is not virtual), thus tree is not a polymorphic base class to begin with.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    17
    Thank you laserlight! That definitely helps.

    That would take care of the default constructor for the classes, but how would I go about adding a constructor with parameters in the oak and pine class?


    The whole project I'm working on right now uses both polymorphism and inheritance. Right now I'm just working with the tree and derived tree classes. After this I have to add them to my forest class and create a forest destructor.
    Last edited by forseti42; 05-07-2008 at 11:55 AM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That would take care of the default constructor for the classes, but how would I go about adding a constructor with parameters in the oak and pine class?
    The same way, of course. You just use the arguments instead.

    The whole project I'm working on right now uses both polymorphism and inheritance. Right now I'm just working with the tree and derived tree classes.
    We're saying that you are using inheritance without the possibility of polymorphism. If your tree class is to be a proper polymorphic base class, it must have at least one virtual member function, and its destructor should be virtual.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    May 2008
    Posts
    17
    Ok, I needed to call the original tree constructor with parameters. It works now.

    I should have reworded my last statement. Right now I'm only working on the Inheritance part, but when apply these new classes in the forest class, I will have to use polymorphism.

    However, I still don't know how to create a base class pointer, which I mentioned in an earlier post.

    Thanks a bunch!
    Ryan

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I should have reworded my last statement. Right now I'm only working on the Inheritance part, but when apply these new classes in the forest class, I will have to use polymorphism.
    Before you even involve the forest class, you should already decide on what member functions should be virtual. In other words, you need to ask yourself: what kind of behaviour do all trees have? Of these kinds of behaviour, what should be fixed for all trees (i.e., they should be non-virtual member functions), and what should be allowed to vary for specific types of trees (i.e., they should be virtual member functions)?

    However, I still don't know how to create a base class pointer, which I mentioned in an earlier post.
    The base class is named tree. A pointer to an object of type T is itself of type T*. Therefore, you would create a base class pointer with:
    Code:
    tree* tree_ptr;
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    17
    I created the tree pointer like so:

    Code:
    tree *treePtr;
    
    treePtr=&a;
    
    (*treePtr).showSymbol(cout);
    
    b.showSymbol(cout);
    
    c.showSymbol(cout);
    However, I now have to go to my forest class and change the grid[21][21] to a grid of tree pointers. I don't feel that my tree pointer is right for what I need to do.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    However, I now have to go to my forest class and change the grid[21][21] to a grid of tree pointers. I don't feel that my tree pointer is right for what I need to do.
    That's the correct thing to do. In C++, polymorphism works through pointers and references.

    Incidentally,
    Code:
    (*treePtr).showSymbol(cout);
    may be replaced with this syntactic sugar:
    Code:
    treePtr->showSymbol(cout);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Your header files have using namespace std; in them which should be avoided (explicitly qualify all std objects with std::).

    The headers also lack a #include <string> statement for the string objects declared within. Right now, your code (may) compile because you just so happen to #include <string> in your source files before you happen to include the relevant header but if for some reason you switch around the order of the #include statements and put #include <tree.h> before #include <string> for example you might find yourself scratching your head at why things suddenly don't compile like they used to.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  12. #12
    Registered User
    Join Date
    May 2008
    Posts
    17
    This is an intro c++ course and they explicitly tell us to use "using namespace std".

  13. #13
    Registered User
    Join Date
    May 2008
    Posts
    17
    Ok, everything is going well, but I'm having trouble with my destructor for my forest class:

    Code:
    //-------------------------------------------------------------------------
    //Default Forest Constructor
    //-------------------------------------------------------------------------
    
    forest::forest()
    {
    tree notree("not_a_tree", 0.0, dead, 1.0, 1);
    tree a("maple", 0.8, live, 1.0, 1);
    tree burnt("burnt", 0, burning, 1.0, 1);
     
      for(int i=0; i<21; i++){
           for(int j=0; j<21; j++){
    
    	     if ( i == 0 || i == 20 || j == 0 || j == 20 ) { 
                 
                   (*grid[i][j]) = notree ;
                 }
                 else {
                   (*grid[i][j]) = a;
                 }
            }
       }
    }
    
    //-------------------------------------------------------------------------
    //Default Forest Destructor
    //-------------------------------------------------------------------------
    
    forest::~forest();
    {
      for(int i=0; i<21; i++){
          for(int j=0; j<21; j++){
          
             if(grid[i][j]){
    
                delete grid[i][j];
                grid[i][j]=NULL;
             }
          }
      }
    }
    However, this isn't working.
    Here is the compiler error:
    Code:
    forest.cpp:39: error: declaration of ‘forest::~forest()’ outside of class is not definition
    forest.cpp:40: error: expected unqualified-id before ‘{’ token
    Thanks a bunch!
    Ryan

  14. #14
    Registered User
    Join Date
    May 2008
    Posts
    17
    Ok, everything is going well, but I'm having trouble with my destructor for my forest class:

    Code:
    //-------------------------------------------------------------------------
    //Default Forest Constructor
    //-------------------------------------------------------------------------
    
    forest::forest()
    {
    tree notree("not_a_tree", 0.0, dead, 1.0, 1);
    tree a("maple", 0.8, live, 1.0, 1);
    tree burnt("burnt", 0, burning, 1.0, 1);
     
      for(int i=0; i<21; i++){
           for(int j=0; j<21; j++){
    
    	     if ( i == 0 || i == 20 || j == 0 || j == 20 ) { 
                 
                   (*grid[i][j]) = notree ;
                 }
                 else {
                   (*grid[i][j]) = a;
                 }
            }
       }
    }
    
    //-------------------------------------------------------------------------
    //Default Forest Destructor
    //-------------------------------------------------------------------------
    
    forest::~forest();
    {
      for(int i=0; i<21; i++){
          for(int j=0; j<21; j++){
          
             if(grid[i][j]){
    
                delete grid[i][j];
                grid[i][j]=NULL;
             }
          }
      }
    }
    However, this isn't working.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The error sounds like it is coming because you didn't declare the destructor in the header file.

    I'm curious about your delete in the destructor. Is it really necessary? I don't see where you ever use new.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polymorphism - "pointers" or "references"?
    By Petike in forum C++ Programming
    Replies: 10
    Last Post: 06-04-2009, 05:06 PM
  2. A C++ program examples showing Polymorphism, please help.
    By MarkSquall in forum C++ Programming
    Replies: 19
    Last Post: 06-06-2008, 04:41 AM
  3. Question on polymorphism
    By 6tr6tr in forum C++ Programming
    Replies: 3
    Last Post: 05-06-2008, 09:05 AM
  4. Replies: 3
    Last Post: 10-31-2005, 12:05 PM
  5. Polymorphism & Overloaded Operators :: C++
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 09-13-2002, 08:40 PM