Thread: Polymorphism

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    25

    Polymorphism

    I would like to know if I can do this cin>>Player1 and if so how. Player1 is a base class pointer to a derived class. the base class is called Player of course is an abstract class, a Human class is derived from Player. Player has a Board object defined in it. My code so far is as follows

    //Human class implementation
    Code:
    //**********************************************************
    //Function: Constructor
    //PreCondition: Valid file name
    //PostCondition: A board object is created
    //**********************************************************
    
    Human::Human(const string name) : Player(name)
    {
    }
    
    //**********************************************************
    //Function: acquires attack points from user and process
    //the points unto opponents board
    //PreCondition:points are valid points on the board
    //PostCondition:at attack point
    //**********************************************************
    
    void Human::Attack(int row, int column)
    {
      Player::Attack(row,column);
    }
    
    //**********************************************************
    //Function: gets number of attack points
    //PreCondition: None
    //PostCondition:number of attack points is sent to function
    //caller.
    //**********************************************************
    
    
    const int Human::GetCounter()const
    {
      return Player::GetCounter();
    }
    
    
    //******************************************************************
    //Function     : Checks for hit or a miss
    //PreCondition : none
    //PostCondition: returns true if the square contains a hit or miss
    //******************************************************************
    
    const bool Human::CheckForHitMiss(const int& row, const int& col) const
    {
      return (Player::CheckForHitMiss(row,col));
     
    }
    
    //******************************************************************
    //Function     : Checks whether attack points have a hit on it
    //PreCondition : none
    //PostCondition: true is returned if it was a hit and false if not
    //******************************************************************
    
    
    const bool Human::CheckForHit(const int& row, const int& col) const
    {
      return (Player::CheckForHit(row,col));
     
    }
    
    
    
    //********************************************************************
    //Function      : Retrieves attack points from user
    //PreCondition  :input from user,row and column, is correct
    //PostCondition : attack points are store for later retrieval
    //********************************************************************
    
    
    void Human::GetAttckPnts()
    {
      char user_row;
      string garbage;
      bool control;
    
      while(control != true)
        {
         cout<<endl<< "Please enter where you would like to attack (row column) (ex: A 1): ";
         cin>>user_row;
         cin>>m_col;
         cout<<endl<<endl;
         char c;
    
         //make sure input was no more than two characters
    
         c =cin.peek();
    
         if( c != '\n'){
          cout<<"Only the first two characters have been accepted as attack points!!!"<<endl;
          cin>>garbage;
         }
    
         //change input to integers
    
         SwitchFunc(user_row);
     
         if((m_row == -1) || (m_col < 0) || (m_col > 9))
          {
            cerr<<"Invalid Input Please Re-enter: "<<endl;
    	control = false;
          }
         else
          control = true;
        }
      
    }
    
    //********************************************************************
    //Function      :Switches char row value to integer
    //PreCondition  :valid input is entered
    //PostCondition :integer form of row is entered
    //********************************************************************
    
    
    void Human::SwitchFunc(const char& user_row)
     {
       switch ( user_row ) {
       case 'A':
         m_row = 0;
         break;
       case 'B':
         m_row = 1;
         break;
       case 'C':
         m_row = 2;
         break;
       case 'D':
         m_row = 3;
         break;
       case 'E':
         m_row = 4;
         break;
       case 'F':
         m_row = 5;
         break;
       case 'G':
         m_row = 6;
         break;
       case 'H':
         m_row = 7;
         break;
       case 'I':
         m_row = 8;
         break;
       case 'J':
         m_row = 9;
         break;
       default:
         m_row = -1;
         break;
       }
    }
    
    //**********************************************************
    //Function     : gets row value of board
    //PreCondition : none
    //PostCondition: row value is returned
    //**********************************************************
      
    const int Human::GetRow()const
    {return m_row;}
    
    
    //**********************************************************
    //Function     : gets column value of board 
    //PreCondition : none
    //PostCondition: col value is returned
    //**********************************************************
    
    const int Human::GetCol()const
    {return m_col;}
    
    
    
    //**********************************************************
    //Function     : Prints Human Player board to the screen
    //PreCondition : None
    //PostCondition: Human Board is sent to the screen with
    //               updated attacks.
    //**********************************************************
    
    
    ostream& operator<<(ostream& out, const Human& Human)
    {
      out<<Human.Player::GetBoard();
      return out;
    }
    
    
    //**********************************************************
    //Function: Read Board into vector
    //PreCondition: Valid file name
    //PostCondition: Human board is read into a vector through
    //a board object
    //**********************************************************
    
    
    istream &operator>> (istream& in, Human& Human)
    {
      in>>Human::Player;
      return in;
    }
    //Player class header
    Code:
    
    class Player{
    
      //******************************************************************
      //Function     :Prints Player board to the screen
      //PreCondition :None
      //PostCondition:Board is outputted to the screen
      //******************************************************************
    
      friend ostream& operator<<(ostream&, const Player&);
    
    
      //******************************************************************
      //Function     : Creates a board from a file
      //PreCondition : valid file name and file can be opened
      //PostCondition: Board object is created using a file
      //******************************************************************
    
      friend istream& operator>>(istream&, Player&);
    
    
    
     public:
    
      //******************************************************************
      //Function     :Constructor
      //PreCondition :valid file name
      //PostCondition:Board object is created
      //******************************************************************
    
      Player(const string&);
    
    
      //******************************************************************
      //Function     : Virtual Destructor
      //PreCondition : None
      //Postcondition: None
      //******************************************************************
    
    
      virtual ~Player();
    
    
      //******************************************************************
      //Function     : initializes board with a some ships
      //PreCondition : not attempting a self copy
      //PostCondition: players board now has ships stored on them and ready
      //               to begin game
      //******************************************************************
    
    
      void SetBoard(const Board&);
    
    
      //******************************************************************
      //Function     :Gets the Board object
      //PreCondition :None
      //PostCondition:Board object is returned
      //******************************************************************
    
    
      Board GetBoard()const;
    
     
      //******************************************************************
      //Function     : Opponent process recent attack 
      //PreCondition : None
      //PostCondition: Result is stored on Players Board
      //******************************************************************
    
    
      virtual void Attack(const int&, const int&);
    
    
      //******************************************************************
      //Function     : Retrieves attack points from Player
      //PreCondition : valid attack points are entered
      //PostCondition: if valid attack points are entered Program retrieves
      //               a true and proceeds to retrieve the attack points
      //******************************************************************
    
    
      virtual void  GetAttckPnts() =0;
    
    
      //******************************************************************
      //Function     : Gets valid row of attack points
      //PreCondition : None
      //PostCondition: valid row is sent to the function caller
      //******************************************************************
    
    
      virtual const int GetRow()const = 0;
    
    
      //******************************************************************
      //Function     : Gets valid column of attack points
      //PreCondition : None
      //PostCondition: valid col is sent to the function caller
      //******************************************************************
    
    
      virtual const int GetCol()const = 0;
    
    
      //******************************************************************
      //Function     : Retrieves number of ships on the board
      //PreCondition : None
      //PostCondition: None
      //******************************************************************
    
      virtual const int GetCounter()const =0;
    
    
      //******************************************************************
      //Function     : boolean function to check if board square has a hit
      //PreCondition : None
      //PostCondition: returns true if there is a hit on the square
      //******************************************************************
    
    
      virtual const bool CheckForHit(const int&, const int&) const =0;
    
    
      //******************************************************************
      //Function     : boolean fucntion to check if board square has a hit
      //               or miss
      //PreCondition : None
      //PostCondition: returns true if there is a hit or miss on the square
      //******************************************************************
    
      virtual const bool CheckForHitMiss(const int&, const int&) const =0;
    
    
     private:
    
      Board PlayerBoard;
    
    
    };
    
    #endif
    //Board class implementation
    Code:
    
    //*******************  Static Data Member intializers  ***************
    
    const string Board::m_Ship = "S";
    const string Board::m_Miss = "M";
    const string Board::m_Hit = "H";
    const string Board::m_BoardChar = "o";
    
    
    //Static data members accesors
    
    //*********************************************************************
    //Function     : Gets the string M representing a miss
    //Precondition :
    //PostCondition:
    //*********************************************************************
    
    const string Board::GetMiss(){return m_Miss;}
    
    //*********************************************************************
    //Function     : Gets the string H representing a Hit
    //Precondition :
    //PostCondition:
    //*********************************************************************
    
    const string Board::GetHit(){return m_Hit;}
    
    
    //*********************************************************************
    //Function     : Constructor
    //Precondition : Valid filename has been entered
    //PostCondition: All members of the class are initialized. File has
    //been opened.
    //*********************************************************************
    
    
    Board::Board(const string file)
    {
      m_filename = file;
      m_counter = 0;
     
      m_BoardVectors.resize(10);
      m_TrackerBoard.resize(10);
      m_TempVect.resize(10);
    
      OpenFile();
    
    }
    
    
    
    //**********************************************************
    //Function     :Copy constructor
    //PreCondition :None
    //PostCondition:Object A is copied into Object B
    //**********************************************************
    
    Board::Board(const Board& BoardObject)
    {
      m_filename = BoardObject.m_filename;
      m_counter = BoardObject.m_counter;
    
      unsigned int size = BoardObject.GetSize();
      m_BoardVectors.resize(size);
      m_TrackerBoard.resize(size);
     
      m_BoardVectors = BoardObject.m_BoardVectors;
      m_TrackerBoard = BoardObject.m_TrackerBoard;
    
    }
    
    
    //**********************************************************
    //Function     :Assignment operator
    //PreCondition :not attempting self copy
    //PostCondition:Object A = Object B
    //**********************************************************
    
    const Board& Board::operator= (const Board& rhs)
    { 
      if(this != &rhs)
        {
         m_filename = rhs.m_filename;
         m_counter = rhs.m_counter;
    
         unsigned int size = rhs.GetSize();
         m_BoardVectors.resize(size);
         m_TrackerBoard.resize(size);
     
         m_BoardVectors = rhs.m_BoardVectors;
         m_TrackerBoard = rhs.m_TrackerBoard;
        }else
        cout<<"Attempting a self copy"<<endl;
    
      return (*this);
    
    }
    
    
    //********************************************************************
    //Function   :Opens file containing boards
    //PreCondition :valid file name is inputed
    //PostCondition:file is open using ifstream
    //********************************************************************
    
    void Board::OpenFile()
    {
      //opening file
    
      m_infile.open(m_filename.c_str());
    
      //making sure correct m_filename has been entered
    
      if(!m_infile.is_open())
        {
          cerr<<"!!!!!!!  Error opening the file  !!!!!!"<<endl;
          exit(1);
        }
    
    }//end of open file
    
    
    //**********************************************************
    //Function     :Checks the Board squares to see if they contain
    //              a hit or miss
    //PreCondition :None
    //PostCondition:returns string hit or miss
    //**********************************************************
    
    
    const bool Board::I........(const int row, const int col)
    {
     if(m_BoardVectors[row][col] == m_Hit)
      return true;
     else
       return false;
    }
    
    const bool Board::IsMiss(const int row, const int col)
    {
     if(m_BoardVectors[row][col] == m_Miss)
       return true;
     else
       return false;
    }
    
    
    const bool Board::I........OrMiss(const int row, const int col)
    {
      if((m_BoardVectors[row][col] == m_Hit) || (m_BoardVectors[row][col] == m_Miss))
       return true;
      else
        return false;
    }
    
    //*********************************************************************
    //Function     :Records a hit or miss for each attack
    //Precondition :The user enters a correct row or col
    //PostCondition:The row,col will now list hit or miss for the users board
    //*********************************************************************
    
    
    void Board::RecordAttack(const int row, const int col)
    {
    
      if (m_BoardVectors[row][col]  == m_Ship){
        cout<<endl<<"!!!!!!!!!!You have hit a ship!!!!!!!!!"<<endl<<endl;
        m_BoardVectors[row][col] = m_Hit;
        m_TrackerBoard[row][col] = m_Hit;
        m_counter--;
      }
      else if((m_BoardVectors[row][col]  == m_Hit)||(m_BoardVectors[row][col] == m_Miss)){
        cout<<endl<<"!!!!!!!!!!!!  Choosen Points Already  !!!!!!!!!!"<<endl<<endl;
      }
      else{
        cout <<endl<<"!!!!!!!!!You have missed!!!!!!!!!!!!"<<endl<<endl;
        m_BoardVectors[row][col] = m_Miss;
        m_TrackerBoard[row][col] = m_Miss;
        
      }
    
    }
    
    //*********************************************************************
    //Function     :Gets m_counter
    //Precondition :None
    //PostCondition:Accounts for how many valid hits on a board
    //*********************************************************************
    
    int Board::GetCounter()const
    {
     return m_counter;
    }
    
    //*********************************************************************
    //Function      : Gets the size of Board
    //PreCondition  : None
    //PostCondition : size is returned to the function called
    //*********************************************************************
    
    unsigned int Board::GetSize()const
    {
      return m_TrackerBoard.size();
    }
    
    //********************************************************************
    //Function     : Prints Board output to the screen
    //PreCondition : None
    //PostCondition: User recent attack is put out to the screen
    //********************************************************************
    
    
    ostream &operator<<(ostream &out, const Board &A_Board)
    {
      //variable declarations
    
      int letter = 65;
      const string header = "  0 1 2 3 4 5 6 7 8 9";
    
      //Printing board
    
    
      out<<header<<endl;
    
      for (unsigned int l =0; l<A_Board.GetSize(); l++)
        {
    
          out << char (letter)<< " ";
          for (unsigned int k=0; k<A_Board.GetSize(); k++)
            {
    
              out<< A_Board.m_TrackerBoard[l][k]<<" ";
    
            }// end of inner for
    
          letter++;
          out<<endl;
    
        }//end of outer for
    
      return out;
    
    }//end of overload ostream 
    
    //*********************************************************************
    //Function     :ReadBoard
    //Precondition :Valid file name has been entered
    //PostCondition:The user board is initialized with the filename entered
    //*********************************************************************
    
    istream& operator>> (istream& in, Board& A_Board)
    {
     
      //Initialize Boards
    
      for (unsigned int i = 0; i<A_Board.GetSize(); i++)
        {
    
          for (unsigned int j=0; j<A_Board.GetSize(); j++)
    	{
    	  A_Board.m_infile >> A_Board.m_Row;
    	  if(A_Board.m_Row == A_Board.m_Ship)
    	    {
    	      A_Board.m_counter++;
    	      A_Board.m_TempVect[j]=(A_Board.m_Row)  ;
    	    }else
    	      A_Board.m_TempVect[j] = (A_Board.m_Row);
    	}// end of inner for
    
          A_Board.m_BoardVectors[i] = A_Board.m_TempVect;
    
        }//end of outer for
    
      for (unsigned int i = 0; i<A_Board.GetSize(); i++)
        {
    
          for (unsigned int j=0; j<A_Board.GetSize(); j++)
            {
              A_Board.m_TempVect[j]= (A_Board.m_BoardChar)  ;
            }// end of inner for
    
          A_Board.m_TrackerBoard[i] = A_Board.m_TempVect;
        
        }//end of outer for
    
      return in;
    
    }

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You overload operator << as a non member function and make it a friend of your class.
    See http://www.cs.xu.edu/csci175/notes97m/overloading.html

    This is not about polymorphism, btw.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    25
    within all the classes the function is overloaded as a non member friend function I would like to know how to make the call within the function. So human class is derived from player class which has a board object how can in my overloaded non member friend function say cin<<Player which would then call the overloaded funtion in my board class

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    So human class is derived from player class which has a board object how can in my overloaded non member friend function say cin<<Player which would then call the overloaded funtion in my board class
    One idea is this: the base class implements the overloaded operator<< for I/O streams by using a protected print() virtual function. Classes that inherit from this base class implement the print() function to print themselves according to what is required.
    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 2003
    Posts
    1,619
    Do it this way:

    Add
    virtual void Player::Read(istream & stream) = 0;
    and/or
    virtual void Player::Write(ostream & stream) = 0;
    and of course implement it in every child class.

    Make ONE version of operator>> and/or operator<< which takes a Player& and calls the virtual function to actually do the work.

    There's no other way to do polymorphism where you want a binary operator to be polymorphic for the second operand.
    Last edited by Cat; 11-23-2006 at 01:24 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    25
    Thanks I used what u guys said and it works i basically needed some kind of helper function

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