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();
精彩评论