开发者

calling the correct form of a polymorphic function. c++

开发者 https://www.devze.com 2023-04-04 11:38 出处:网络
I\'m having problems with finding a way to call the right form of a polymorphic function without editing the int main() function.

I'm having problems with finding a way to call the right form of a polymorphic function without editing the int main() function.

void Print(Operator*  someOp); //function definition

int main(int argc, char* const argv[])
{
Operator* ptr = NULL;

...
... //this is the body


void Print(Operator*  someOp)
 // Writes description of card to stdout
 {
    someOp->WriteOperator();         // Hint:  Polymorphic function
 }

}

I kept the main function as concise as possible above, but the whole function is at the bottom for any reference.

ok, so there is a operator class which has a function named void WriteOutput() but then UnaryOp inherits from Operator and also has another void WriteOutput() function

but they output different data. so my question is how can I make main call the right function. I know that if I could edit main I would be able to just set someOp to whatever class I wanted to call but I can't edit main. the only files I can edit are operator.h and UnaryOp.cpp there are more files in the program but they all have the same function call problem so if I can fix this one the rest will be easy.

// main.cpp
//
// Driver program for Card program which is used to test each
// class member function.
//
// DO NOT MODIFY OR SUBMIT THIS FILE
//

// List of allowed include files appear below
#include <iostream>
#include <fstream>
#include <string>
#include "operator.h"
#include "unaryop.h"
#include "binaryop.h"
#include "factorial.h"
#include "plus.h"
#include "minus.h"
#include "times.h"
#include "slash.h"


using namespace std;                     // Global using declaration

void Bar();                              // Prototype for Bar function
void Print(Operator*  someOp);           // Prototype for Print function



// Start of main() function


int main (int argc, char* const argv[])  // Command-line arguments (more on this later)
{
ifstream inputs;       // Input file stream variable    for test file
char op, ch;     // Hold operation and optional char input from test file
string   comment;                      // Holds comment string input from test file
Operator* ptr = NULL;                  // Pointer to abstract operator object
int      operand1,operand2;            // Holds operand values input from test file


 // Output usage message if test input file name is not provided
 if (argc != 2)
  {
   cout << "Usage:\n  project02  <inputfile>\n";
    return 1;
  }

  // Attempt to open test input file -- terminate if file does not open
  inputs.open(argv[1]);
  if (!inputs)
  {
    cout << "Error - unable to open input file" << endl;
    return 1;
  }

  Bar();

  // Process comment line from input file
  getline(inputs, comment);                          // Input file header comment
  cout << endl << comment << endl << endl;           // Output file header comment


  // Below is the primary loop that processes each operation appearing within the test   file.
  // Starts with an initial priming read of first operation

  inputs >> op;                                      // Attempt to input     first test operation from file

  while (inputs)                                     // While Not-EOF
  {
    switch (op)                                      // Process operation input from test file
    {
     case '#':   // Test file comment
            getline(inputs, comment);      // Input and echo the comment appearing in the    test file
            cout << '#' << comment << endl;
            break;

     case 'p':   // Print Operator 
            Print(ptr);
            break;  

     case '~':   // Print Bar
            Bar();                         // Function definition appears at the end of     this file
            break;              

     case 'o':   // Set output to desired value
                 inputs >> operand1;
                 ptr->SetOutput(operand1);
                 break;

     case 's':   // Set symbol to desired value
                 inputs >> ch;
                 ptr->SetSymbol(ch);
                 break;

     case ';':   // Reset operand one and trigger output update
                 inputs >> operand1;
                 {
                   UnaryOp* temp = (UnaryOp*) ptr;    // Treat as a unary operator pointer
                   temp->SetOperand(operand1);
                 }
                 break;

     case ':':   // Reset both operands and trigger output update
                 inputs >> operand1 >> operand2;
                 {
                   BinaryOp* temp = (BinaryOp*) ptr;  // Treat as a binary operator pointer
                   temp->SetOperand1(operand1);       
                   temp->SetOperand2(operand2);
                 }
                 break;

     case 'c':   // Use symbol input from file to invoke appropriate constructor
                 inputs >> op;              // Input symbol
                 try
                 {
                   cout << "Constructor -- ";
                   switch (op)
                   {
                     case '?':  // Operator
                                ptr = new Operator;
                                break;
                     case 'u':  // UnaryOp
                                inputs >> operand1;
                                ptr = new UnaryOp(operand1);
                                break;
                     case '!':  // Factorial
                                inputs >> operand1;
                                ptr = new Factorial(operand1);
                                break;
                     case 'b':  // BinaryOp
                                inputs >> operand1 >> operand2;
                                ptr = new BinaryOp(operand1, operand2);
                                break;
                     case '+':  // Plus
                                inputs >> operand1 >> operand2;
                                ptr = new Plus(operand1, operand2);
                                break;
                     case '-':  // Minus
                                inputs >> operand1 >> operand2;
                                ptr = new Minus(operand1, operand2);
                                break;
                     case '*':  // Times
                                inputs >> operand1 >> operand2;
                                ptr = new Times(operand1, operand2);
                                break;
                     case '/':  // Slash
                                inputs >> operand1 >> operand2;
                                ptr = new Slash(operand1, operand2);
                                break;
                     default:   cout << "Error: unrecognized object" << endl;
                    } // End switch (op)


                    cout << "Successful"; 
                  }  // End try
                  catch ( ... )                // Catch any exception thrown above
                  { 
                    cout << "Failed";  
                  }

                  cout << endl;                  
                      break;

      case 'd':   // Destructor
                  try
                  {
                    cout << "Destructor -- ";
                    delete ptr;                        // Deallocate card 
                   cout << "Successful";
                   ptr = NULL;                        // Make sure that ptr is not a dangling pointer
              }
              catch ( ... )
              {
                cout << "Failed";
              }
              cout << endl;
              break;        

  default:    // Error
              cout << "Error - unrecognized operation '" << op << "'" << endl;
              cout << "Terminating now..." << endl;
                  return 1;
              break;
}

i开发者_如何学运维nputs >> op;                                    // Attempt to input next command
  }

  cout << endl;

  return 0;
}

/************** Implementation of Print() and Bar() functions ********************/

// DO NOT MODIFY THIS CODE

void Bar()
// Bar() -- prints horizontal bar
    {
    cout << "#################################################################" << endl;
    }  // End Bar()


void Print(Operator*  someOp)
// Writes description of card to stdout
{
    someOp->WriteOperator();         // Hint:  Polymorphic function
}

/**************  End of main.cpp  ***************/


The beauty about polymorphism in C++ is that it will always call the right method. You probably neglected to make WriteOperator() virtual. That is the syntax to override behavior of a parent. In this way, you can keep a pointer of the base class type, point it to any child object, and invoke the correct method without casting (A UnaryOp is an Operator after all). This works provided the real type of the underlying object is that of the child.

Inside your Operator.cpp file, it might look something like this:

void Operator::WriteOperator() 
{
    ...
}

And in the header:

virtual void WriteOperator();
0

精彩评论

暂无评论...
验证码 换一张
取 消