调用多态函数的正确形式。 C ++

时间:2011-09-13 21:45:44

标签: c++ function polymorphism call

我在找到一种方法来调用多态函数的正确形式而不编辑int main()函数时遇到了问题。

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
 }

}

我保持主要功能尽可能简洁,但整个功能都在底部供任何参考。

好的,所以有一个运算符类,它有一个名为void WriteOutput()的函数 但是然后UnaryOp继承自Operator并且还有另一个void WriteOutput()函数

但它们会输出不同的数据。 所以我的问题是如何让主要呼叫成为正确的功能。我知道如果我可以编辑main,我可以将someOp设置为我想要调用的任何类,但我无法编辑main。我可以编辑的唯一文件是operator.h和UnaryOp.cpp 程序中有更多的文件,但它们都有相同的函数调用问题,所以如果我能解决这个问题,剩下的就很容易了。

// 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;
}

inputs >> 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  ***************/

1 个答案:

答案 0 :(得分:0)

C ++中关于多态性的美妙之处在于总是调用正确的方法。您可能忽略了WriteOperator() virtual。这是父覆盖行为的语法。通过这种方式,您可以保留基类类型的指针,将其指向任何子对象,并在不进行强制转换的情况下调用正确的方法(A UnaryOp Operator毕竟)。这项工作提供了底层对象的真实类型是孩子的实际类型。

在您的Operator.cpp文件中,它可能如下所示:

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

在标题中:

virtual void WriteOperator();