我正在开发一个涉及使用模板来评估后缀表达式的程序。我不允许以任何方式修改代码;只填写空白,可以这么说(其中大部分已经填补,但错误正在出现)。这就是说:
1)模板标题,模板特化和主程序文件都是独立的。如何在主程序中实现模板?我已经在头文件的末尾使用#include作为专业化替代品。
2)固定
3)在专业化文件中,我是否需要使用#include" templateheader.h"上面使用命名空间std,还是我只是将模板放在每个函数上面?我将在下面发布一个示例。
两个星号标记我们必须填充空白的行。如果它只是一条线的一部分,那么它就是每一边的一颗星。
stackType.h
#pragma once**
// Catherine Stringfellow and Trey Brumley
// A Stack is a ???**
// Class specification for Stack ADT in file StackType.h
using namespace std;
static const int MAXITEMS = 50;
template <class stack>**
class StackType
{
public:
// Class constructors
StackType();
StackType (const StackType & other);
void makeEmpty();
// Function: Sets stack to an empty state.
// Post: Stack is empty.
bool isFull() const;
// Function: Determines whether the stack is full.
// Pre: Stack has been initialized.
// Post: Function value = (stack is full)
bool isEmpty() const;
// Function: Determines whether the stack is empty.
// Pre: Stack has been initialized.
// Post: Function value = (stack is empty)
void push(*stack* item);
// Function: Adds newItem to the top of the stack.
// Pre: Stack has been initialized.
// Post: If (stack is full), PushOnFullStack exception is thrown;
// otherwise, newItem is at the top of the stack.
void pop(*stack* & item);
// Function: Removes top item from the stack and returns it in item.
// Pre: Stack has been initialized.
// Post: If (stack is empty), PopOnEmptyStack exception is thrown;
// otherwise, top element has been removed from stack.
// item is a cop of the removed item.
int getStackNum ();
//Function: returns the number of items in the stack
//Pre: Stack has been initialized
//Post: Returns the number of items in the stack
private:
int top;
stack items[MAXITEMS]; //statically allocated array
};
#include "stackType.cpp";**
stackType.cpp
// Catherine Stringfellow and Trey Brumley
// File: StackType.cpp
// Templated member function implementations for class StackType.
// This is the statically allocated array-based stack.
#include "stack"**
using namespace std;
template <class stack>**
StackType *StackType<stack>*::StackType()
{
top = -1;
}
template <class stack>**
StackType *StackType<stack>*::StackType (const StackType & other)
{
top = other.top;
for (int i=0; i < top; i++)
items[i] = other.items[i];
}
template <class stack>**
StackType*<stack>*::makeEmpty()
{
top = -1;
}
template <class stack>**
*bool StackType<stack>*::isEmpty() const
{
return (top == -1);
}
template <class stack>**
bool StackType*<stack>*::isFull() const
{
return (top == MAXITEMS-1);
}
template <class stack>**
StackType*<stack>*::push(StackType newItem)
{
if( !isFull() )
{
top++;
items[top] = newItem;
}
}
template <class stack>**
StackType*<stack>*::pop( & item)
{
if( !isEmpty() )
{
item = items[top];
top--;
}
}
template <class stack>**
int StackType*<stack>*::getStackNum ()
{
return top+1;
}
主
/* Erik Malone and Catherine Stringfellow and Trey Brumley Date: December-5-2013
File: prog5.cpp
Program Specifications
Narrative: Program that evaluates and converts postfix expressions.
Interface:
Introductory Screen:
"Postfix Calculator and Converter"
Exit Screen:
"Goodbye..."
Input:
numbers in expressions should be separated by a space.
(from keyboard, see attached)
Output:
(all to screen, see attached)
Constants:
STACK_MAX
*/
#include "stack"**
#include <string>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <cctype>
int getValidChoice ();
/* purpose: get valid option choice from menu
prereq: NONE
postcond: int (for a valid choice returned)
*/
void readString(string& s);
/* purpose: Reads a line into a string
recieves: string <s>
returns: NONE
*/
void printString(const string& s);
/* purpose: Prints a string
recieves: const string <s>
returns: NONE
*/
void convertPostfix(string& post, string& result);
/* purpose: converts a prefix expression to infix
recieves: string <post>, string <result>
returns: NONE
*/
void convert(StackType & s, char ch);
/* purpose: pops two operands off a string stack and pushes the result
recieves: string <post>, char <ch>
returns: NONE
*/
void evalPostfix(string& post, double& answer);
/* purpose: calculates the value of the prefix expression
recieves: string <post>, double <answer>
returns: NONE
*/
void evaluate(StackType & s, char ch);
/* purpose: pops two operands off a double stack and pushes the result
recieves: Stack <s>, char <ch>
returns: NONE
*/
void error(int m);
//prints an error message, based on int parametet
//print the introduction and exit screens
void intro();
void outro();
void main()
{
string post;
double answer;
int choice;
//intro screen
intro();
//while user wants to continue
choice = getValidChoice();
while (choice != 3) {
//switch menu options
switch (choice)
{
case 1:
cout<<"Please enter a postfix expression: ";
readString(post);
if (post == "") //error if string empty
error(1);
else
{
evalPostfix(post, answer);
printString(post);
cout<<" = "<<answer<< endl << endl;
}
break;
case 2:
cout<<"Please enter a postfix expression: ";
readString(post);
if (post == "")
error(1);
else
{ string tempString = "";
convertPostfix(post, tempString);
cout<<"Postfix expression: ";
printString(post);
cout<<"\nEpression converted to infix: "<<tempString << endl<<endl;
}
break;
default: //if choice is not recognized print error
error(3);
} //end switch
choice = getValidChoice();
} //end while
outro();
//exit screen on return
system("pause");
}
int getValidChoice ()
{
int choice;
//display menu options
cout<<" Options \n";
cout<< " (1) Evaluate postfix expression " << endl;
cout<< " (2) Convert postfix to infix " << endl;
cout<< " (3) Quit " << endl;
//get menu option
cout<<"Enter option: ";
cin>>choice;
cout <<endl;
//validate menu option
while ((choice < 1) || (choice > 3)) {
cout << "Enter a value between 1 and 3: ";
cin >> choice;
}
return choice;
}
void printString(const string& s)
{
if (s.empty())
cout<<"Empty"; //if string is empty print "empty"
else
cout<<s;
}
void readString(string& s)
{
char temp[40];
cin.ignore(80,'\n'); //clear buffer
cin.getline(temp, 40); //copy line to string
s = temp;
}
void evalPostfix(string& post, double& answer)
{
int index = 0, total = 0;
double tempDbl;
bool negative = false; //to detect negative signs
StackType s; //declare a stack of doubles
//loop index until end of string
while (index < (int) post.length())
{
//pass over spaces in string
while (isspace(post[index]))
index++ ;
//if operator evaluate incrementing index
if (!isdigit(post[index]) &&
!((index+1 < (int) post.length()) &&
(post[index] == '-' && isdigit(post[index+1]))))
//if (!isdigit(post[index]))
evaluate(s, post[index++]);
else
{ //if number, checks for negative sign
if (post[index] == '-')
{
index++;
negative = true;
}
//add up the digits from string
while ((post[index] >= '0') && (post[index] <= '9'))
total = (total * 10) + (post[index++] - '0');
//if there was a negative sign, negate total
if (negative)
{
total = total * -1;
negative = false;
}
//push number onto stack
s.push(total);
total = 0;
}
index++;
}
//pop answer from stack
s.pop(tempDbl);
answer = tempDbl;
}
void evaluate(StackType & s, char ch)
{
double op1, op2;
//check if empty before popping operands
if (!s.isEmpty())
{
s.pop(op2);
if (!s.isEmpty())
{
s.pop(op1);
//push result
switch(ch)
{
case '+':
s.push(op1 + op2);
break;
case '-':
s.push(op1 - op2);
break;
case '*':
s.push(op1 * op2);
break;
case '/':
s.push(op1 / op2);
break;
default:
return;
}
}
}
}
void convertPostfix(string& post, string& result)
{
int index = 0;
string tempString;
StackType s; //declare a stack of strings
//loop index until end of string
while (index < (int) post.length())
{
//pass over spaces in string
if (isspace(post[index]))
index++ ;
//if operator convert incrementing index
if (!isdigit(post[index]) &&
!((index+1 < (int) post.length()) &&
(post[index] == '-' && isdigit(post[index+1]))))
//if (!isdigit(post[index]))
convert(s, post[index++]);
else
{
//clear string
tempString.erase();
//concatenate numbers to string
while (!isspace(post[index]))
tempString = tempString + post[index++];
//push string onto stack
s.push(tempString);
}
index++;
}
//pop resulting string from stack
s.pop(result);
}
void convert(StackType & s, char ch)
{
string op1, op2, tempString;
//check if empty before popping
if (!s.isEmpty())
{
s.pop(op2);
if (!s.isEmpty())
{
s.pop(op1);
//constructing string for result
tempString = tempString + "( ";
tempString = tempString + op1;
//concatenate sign to string
switch(ch)
{
case '+':
tempString = tempString + " + ";
break;
case '-':
tempString = tempString + " - ";
break;
case '*':
tempString = tempString + " * ";
break;
case '/':
tempString = tempString + " / ";
break;
default:
return;
}
//adding rest of the string
tempString = tempString + op2;
tempString = tempString + " )";
//push resulting string onto stack
s.push(tempString);
}
}
}
void error(int m)
{
system("cls"); //clear screen
cout<<"\a"; //system beep
//displays error message according to parameter passed
switch (m)
{
case -1:
cout<<"INTERNAL ERROR";
break;
case 1:
cout<<"ERROR - Postfix expression empty.";
break;
case 3:
cout<<"ERROR - invalid entry.";
break;
default:
cout <<"UNKNOWN ERROR.";
}
cout << endl << endl;
}
void intro()
{
system("cls"); //clear screen
//displays welcome message
cout<<"Postfix Calculator and Converter\n\n";
}
void outro()
{
cout<<"Goodbye...\n\n"; //display exit message
}
答案 0 :(得分:0)
至于2)它必须是std :: string,或者你可以说
using std::string;
或
using namespace std;
然后你应该能说只是字符串。除非你从std ::
中提取很多东西,否则我会推荐前者琐事的其他部分:
您不需要stack.cpp,只需实现stack.h中的函数,例如
模板 class Stack { ...。 void doSomething(ElementType&amp; object){...} ...。 };
这往往更清洁。你也可以在线外完成,但它仍然需要在同一个文件中,如果你在线外,你需要在每个函数前面加上模板关键字
答案 1 :(得分:0)
您应该使用模板参数的名称切换类的名称,这将更有意义。这将成为
template <typename StackType>
class Stack
{
...
};
例如
void push(stack item);
将是
void push(StackType item);
1)您可以将声明和方法的定义放在单独的文件中,但是您需要像最后一样将它们包含在最后,但我建议您将stack.cpp重命名为stack.inl(.inl表示内联)或其他什么。
3)如果使用上述2个文件,则无需在stack.cpp / inl中包含stack.h。想想这就像它是同一个文件。并且要小心使用命名空间std,因为包含你的stack.h的每个人都将“使用namespace std”,这可能会导致问题......
最后,您的源代码中没有模板专门化,并且没有专门化文件这样的东西。但是,模板专业化确实存在,并且它可能不是您所期望的。更多信息here