列表节点指针'未在此范围内声明'?

时间:2013-02-10 23:24:11

标签: c++ list linked-list g++

我已经搜索过高低,试图对此进行调试,但到目前为止,我无法弄明白。

我在一个名为DataList.h的文件中有一个类声明,一个名为DataList.cc文件的文件中的方法,以及一个单独的.cc文件中的主程序。

DataList.cc有一个#include头,包含DataList.h。

每当我跑

g++ DataList.cc

在Ubuntu终端,它吐出

DataList.cc: In function ‘bool TransactOnce(int&, TRANS&, std::string&)’:
DataList.cc:395:2: error: ‘ListNodeT’ was not declared in this scope
DataList.cc:395:13: error: ‘nodeTPtr’ was not declared in this scope
DataList.cc:396:13: error: ‘headTrans’ was not declared in this scope

奇怪的是,我在DataList.cc中的其他成员函数中声明了这些类型的变量ALL OVER THE PLACE,但编译器除了上面的那些之外没有给我任何其他错误。我试图找出g ++不喜欢那个函数中那些特定声明的内容。

'ListNodeT'是我的主类中的结构,结构包含指向另一个结构类型对象的指针。 'nodeTPtr'只是指向'ListNodeT'对象的指针,并且 'headTrans'是一个指针(私有地包含在类中),指向ListNodeT类型的对象,特别是链表中的第一个节点。

“List”类用于链接列表。

这是“DataList.h”文件:

#ifndef DATALIST_H
#define DATALIST_H

#include <iostream>
#include <fstream>
#include <ostream>
#include <iomanip>

using namespace std;
const int MAXDISCIPLINES = 4;
const int MAXBREEDS = 4;
struct HORSE {
    int    ID;
    string    name; // maximum 25 alphanumeric characters, spaces included
    double    height;// in inches?
    int    age;
    char    genderCode;//'m', 'f', 'M', or 'F'
    int    breed; 
    int    disciplineCount;
    int    discipline[MAXDISCIPLINES];  
    double    lowBid; // minimum selling price
};
struct TRANS {
    char transCode;    //'A' for add, 'D' for delete or updating disciplines, or 'P' for updating lowBid price
    HORSE transHorse;
};
class List {
    private:
        struct ListNodeT {
            TRANS trans;
            struct ListNodeT *nextLNT;
        };
        ListNodeT *headTrans;

        struct ListNodeH {
            HORSE horse;
            struct ListNodeH *nextLNH;
        };
        ListNodeH *headHorse;
    public:
        //ListNodeH *headHorse;
        //ListNodeT *headTrans;

        List();
        List(const List &obj);
        ~List();
        bool InsertHorse(HORSE newHorse);
        bool InsertTrans(TRANS newTrans);

        bool DeleteHorse(int target);
        bool DeleteTrans(int target);

        bool ViewHorse(int target, HORSE &viewHorse);
        bool ViewTrans(int target, TRANS &viewTrans);

        int getNumHorses();
        void getNumTrans(int &numA, int &numDel, int &numDisc, int &numP);

        bool TransactOnce(int &skip, TRANS &thisTrans, string &failString);
        bool UpdateDisc(TRANS thisTrans);
        bool UpdatePrice(TRANS thisTrans);

        void ReportOneTransaction(fstream &strm, TRANS thisTrans);


};    //end List class definition
//methods are in file DataList.cc and compiled separately.

#endif

以下是我的“DataList.cc”文件。有问题的“TransactOnce()”是最底层的。

#include "DataList.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <ostream>
#include <iomanip>

using namespace std;

//constructor
List::List(){
    headHorse = NULL;
    headTrans = NULL;
}

//copy constructor
List::List(const List &obj){
    //copy the linked list of horses
    ListNodeH *nodeHPtr;
    ListNodeH **newListHPtr;
    headHorse = NULL;
    newListHPtr = &headHorse;    //means &(this->headHorse), not &(obj.headHorse)
    nodeHPtr = obj.headHorse;
    while (nodeHPtr != NULL) {
        *newListHPtr = new ListNodeH;
        (*newListHPtr)->horse = nodeHPtr->horse;
        (*newListHPtr)->nextLNH = NULL;
        newListHPtr = &((*newListHPtr)->nextLNH);
        nodeHPtr = nodeHPtr->nextLNH;
    }

    //copy the linked list of transactions
    ListNodeT *nodeTPtr;
    ListNodeT **newListTPtr;
    headTrans = NULL;
    newListTPtr = &headTrans;
    nodeTPtr = obj.headTrans;
    while (nodeTPtr != NULL) {
        *newListTPtr = new ListNodeT;
        (*newListTPtr)->trans = nodeTPtr->trans;
        (*newListTPtr)->nextLNT = NULL;
        newListTPtr = &((*newListTPtr)->nextLNT);
        nodeTPtr = nodeTPtr->nextLNT;
    }
}//end copy constructor

//destructor
List::~List(){
    //destroy the list of horses
    ListNodeH *nodeHPtr;
    ListNodeH *nextHNode;
    nodeHPtr = headHorse;
    while(nodeHPtr != NULL){
        nextHNode = nodeHPtr->nextLNH;
        delete nodeHPtr;
        nodeHPtr = nextHNode;
    }//end walkthrough

    //destroy the list of transactions
    ListNodeT *nodeTPtr;
    ListNodeT *nextTNode;
    nodeTPtr = headTrans;
    while(nodeTPtr != NULL){
        nextTNode = nodeTPtr->nextLNT;
        delete nodeTPtr;
        nodeTPtr = nextTNode;
    }//end walkthrough
}//end List::~List()

//********************************************************************
// FUNCTION NAME: InsertHorse()
// FUNCTION PURPOSE: inserts a new HORSE struct into our list
// INPUT PARAMETERS:
//      1. HORSE newHorse    - the object of type DATA to be inserted into the List.
//RETURN VALUE – bool
//********************************************************************
bool List::InsertHorse(HORSE newHorse){
    bool success = false;
    ListNodeH *newNodeHPtr;
    ListNodeH *nodeHPtr;
    ListNodeH *prevNodeHPtr = NULL;

    newNodeHPtr = new ListNodeH;    
    newNodeHPtr->horse = newHorse;

    if(!headHorse){    //if head==NULL, our list is empty
        headHorse = newNodeHPtr;
        newNodeHPtr->nextLNH = NULL;
        success = true;
    }
    else {    //perhaps add?  Our list is currently not empty.
        nodeHPtr = headHorse;
        //prevNodePtr;    [sic] in my notes.  I think it's supposed to be prevNodePtr = NULL;, but this should already be true
        while(nodeHPtr != NULL && nodeHPtr->horse.ID < newHorse.ID){    //searches for approriate place
            prevNodeHPtr = nodeHPtr;
            nodeHPtr = nodeHPtr->nextLNH;
        }
        if(nodeHPtr != NULL && nodeHPtr->horse.ID == newHorse.ID){    //checks for duplicates
            delete newNodeHPtr;
            success = false;    //note: this is the only way that Insert could return false
        }
        else {    //insert the node
            success = true;
            newNodeHPtr->nextLNH = nodeHPtr;
            if(prevNodeHPtr == NULL)        //we're at the beginning of the list
                headHorse = newNodeHPtr;
            else                //not at the beginning of the list
                prevNodeHPtr->nextLNH = newNodeHPtr;
        }//successful insertion
    }
//    delete newNodeHPtr;
    return success;
}
//end List::InsertHorse()


//********************************************************************
// FUNCTION NAME: InsertTrans()
// FUNCTION PURPOSE:     inserts a new TRANS struct into our list.
//            if the transaction is trying to delete or update a horse that does not exist,
//            returns false, and transaction is not inserted.
// INPUT PARAMETERS:
//      1. TRANS newTrans    - the object of type TRANS to be inserted into the List.
//RETURN VALUE – bool
//********************************************************************
bool List::InsertTrans(TRANS newTrans){
    bool success = false;
    ListNodeT *newNodeTPtr;
    ListNodeT *nodeTPtr;
    ListNodeT *prevNodeTPtr = NULL;

    newNodeTPtr = new ListNodeT;    
    newNodeTPtr->trans = newTrans;

    HORSE dummyHorse;    //dummy variable to be passed by reference to ViewHorse()

    //we need to ensure a few things
        //no duplicate IDs in transactions
        //no Del, Disc, or P transactions for which the horse dosn't already exist in inventory


    if(!headTrans){    //if head==NULL, our list is empty
        headTrans = newNodeTPtr;
        newNodeTPtr->nextLNT = NULL;
        success = true;
    }
    else {    //perhaps add?  Our list is currently not empty.
        nodeTPtr = headTrans;
        //prevNodePtr;    [sic] in my notes.  I think it's supposed to be prevNodePtr = NULL;, but this should already be true
        while(nodeTPtr != NULL && nodeTPtr->trans.transHorse.ID < newTrans.transHorse.ID){    //searches for approriate place
            prevNodeTPtr = nodeTPtr;
            nodeTPtr = nodeTPtr->nextLNT;
        }
        //check for duplicates
        if(nodeTPtr != NULL && nodeTPtr->trans.transHorse.ID == newTrans.transHorse.ID){
            delete newNodeTPtr;
            success = false;
        }
        //in the case of Delete or Update transactions for which the horse does not already exist in inventory
        else if((newTrans.transCode == 'D' || newTrans.transCode == 'P') && !List::ViewHorse(newTrans.transHorse.ID, dummyHorse)){
            delete newNodeTPtr;
            success = false;
        }
        else {    //insert the transaction node
            success = true;
            newNodeTPtr->nextLNT = nodeTPtr;
            if(prevNodeTPtr == NULL)        //we're at the beginning of the list
                headTrans = newNodeTPtr;
            else                    //not at the beginning of the list
                prevNodeTPtr->nextLNT = newNodeTPtr;
        }//successful insertion
    }
//    delete newNodeTPtr;
    return success;
}//end List::InsertTrans()


//********************************************************************
// FUNCTION NAME: DeleteHorse()
// FUNCTION PURPOSE: deletes a HORSE struct from our object of class List.
// INPUT PARAMETERS:
//      1. int target    - the ID of the object of type HORSE to be deleted from List
//RETURN VALUE – bool
//********************************************************************
bool List::DeleteHorse(int target){
    bool success = false;
    ListNodeH *nodeHPtr;    
    ListNodeH *prevHPtr;

    if (!headHorse)    //empty list
        success = false;
    else if (headHorse->horse.ID == target) {    //found target at the beginning of list, delete it
        nodeHPtr = headHorse->nextLNH;
        delete headHorse;
        headHorse = nodeHPtr;
        success=true;
    }
    else {    // maybe delete?
        nodeHPtr = headHorse;
        while(nodeHPtr!=NULL && nodeHPtr->horse.ID < target){    //searching...
            prevHPtr = nodeHPtr;
            nodeHPtr = nodeHPtr->nextLNH;
        }
        if(nodeHPtr == NULL && nodeHPtr->horse.ID != target)    //we're at the end of the list, and if target's not here...
            success=false;                    //deletion failed.  This is the only case where Delete() returns false.
        else {                        //we're between the beginning and end, and we found the target
            prevHPtr->nextLNH = nodeHPtr->nextLNH;
            delete nodeHPtr;                //delete target.
            success = true;
        }
    }
    return success;
}

//********************************************************************
// FUNCTION NAME: DeleteTrans()
// FUNCTION PURPOSE: deletes a TRANS struct from our object of class List.
// INPUT PARAMETERS:
//      1. int target    - the ID of the object of type TRANS to be deleted from List
//RETURN VALUE – bool
//********************************************************************
bool List::DeleteTrans(int target){
    bool success = false;
    ListNodeT *nodeTPtr;    
    ListNodeT *prevTPtr;

    if (!headTrans)    //empty list
        success = false;
    else if (headTrans->trans.transHorse.ID == target) {    //found target at the beginning of list, delete it
        nodeTPtr = headTrans->nextLNT;
        delete headTrans;
        headTrans = nodeTPtr;
        success=true;
    }
    else {    // maybe delete?
        nodeTPtr = headTrans;
        while(nodeTPtr!=NULL && nodeTPtr->trans.transHorse.ID < target){    //searching...
            prevTPtr = nodeTPtr;
            nodeTPtr = nodeTPtr->nextLNT;
        }
        if(nodeTPtr == NULL && nodeTPtr->trans.transHorse.ID != target)    //we're at the end of the list, and if target's not here...
            success=false;                    //deletion failed.  This is the only case where Delete() returns false.
        else {                        //we're between the beginning and end, and we found the target
            prevTPtr->nextLNT = nodeTPtr->nextLNT;
            delete nodeTPtr;                //delete target.
            success = true;
        }
    }
    return success;
}


//********************************************************************
// FUNCTION NAME: ViewHorse()
// FUNCTION PURPOSE: finds the HORSE struct whose ID is target, then returns the HORSE by reference.
// INPUT PARAMETERS:
//      1. int target        - the ID to be searched for
//      2. HORSE &viewHorse    - the object of type HORSE to be found and returned (by reference)
//RETURN VALUE – bool
//********************************************************************
//returns by reference the HORSE in the list with ID == target
//if View() returns false, then the target was not found and &viewHorse was not changed by ViewHorse().
bool List::ViewHorse(int target, HORSE &viewHorse){
    bool success = false;
    ListNodeH *nodeHPtr;
    nodeHPtr = headHorse;        //start at the beginning of the list

    while(nodeHPtr != NULL && nodeHPtr->horse.ID < target)    //search...
        nodeHPtr = nodeHPtr->nextLNH;

    //which test failed?
    if(nodeHPtr == NULL || nodeHPtr->horse.ID != target)    //we're at the end of the list, or didn't find the target.
        success = false;                //Note: this is the ONLY way that ViewHorse() returns false.
    else {        //nodeHPtr != NULL && nodeHPtr->horse.ID == target, we found the target
        success = true;
        viewHorse = nodeHPtr->horse;    //return by reference the HORSE in the list with ID == target
    }
    return success;
}//end List::ViewHorse()


//********************************************************************
// FUNCTION NAME: ViewTrans()
// FUNCTION PURPOSE: finds the TRANS struct whose ID is target, then returns the TRANS by reference.
// INPUT PARAMETERS:
//      1. int target        - the ID to be searched for
//      2. TRANS &viewTrans    - the object of type TRANS to be found and returned (by reference)
//RETURN VALUE – bool
//********************************************************************
//returns by reference the TRANS in the list with ID == target
//if ViewTrans() returns false, then the target was not found and &viewTrans was not changed by ViewTrans().
bool List::ViewTrans(int target, TRANS &viewTrans){
    bool success = false;
    ListNodeT *nodeTPtr;
    nodeTPtr = headTrans;        //start at the beginning of the list

    while(nodeTPtr != NULL && nodeTPtr->trans.transHorse.ID < target)    //search...
        nodeTPtr = nodeTPtr->nextLNT;

    //which test failed?
    if(nodeTPtr == NULL || nodeTPtr->trans.transHorse.ID != target)    //we're at the end of the list, or didn't find the target.
        success = false;                //Note: this is the ONLY way that ViewTrans() returns false.
    else {        //nodeTPtr != NULL && nodeTPtr->horse.ID == target, we found the target
        success = true;
        viewTrans = nodeTPtr->trans;    //return by reference the TRANS in the list with ID == target
    }
    return success;
}//end List::ViewTrans

//********************************************************************
// FUNCTION NAME: getNumHorses()
// FUNCTION PURPOSE: returns the number of nodes in our list of horses
// INPUT PARAMETERS: [none]
//RETURN VALUE – int
//********************************************************************
int List::getNumHorses(){
    int horseCounter = 0;
    ListNodeH *nodeHPtr;
    nodeHPtr = headHorse;
    while(nodeHPtr != NULL){
        nodeHPtr = nodeHPtr->nextLNH;
        horseCounter++;
    }
    return horseCounter;
}//end List::getNumHorses()
//********************************************************************
// FUNCTION NAME: getNumTrans()
// FUNCTION PURPOSE: returns (by reference) the numbers of various types of transactions in our list of transactions
// INPUT PARAMETERS:
//    1.int &numA    - number of "Add" transactions
//    2.int &numDel    - number of "Delete" transactions
//    3.int &numDisc    - number of "update discipline" transactions
//    4.int &numP    - number of "update lowBid" transactions
//RETURN VALUE – void
//********************************************************************
void List::getNumTrans(int &numA, int &numDel, int &numDisc, int &numP){
    numA = 0;
    numDel = 0;
    numDisc = 0;
    numP = 0;

    ListNodeT *nodeTPtr;
    nodeTPtr = headTrans;

    while(nodeTPtr != NULL){
        if(nodeTPtr->trans.transCode == 'A')
            numA++;
        else if(nodeTPtr->trans.transCode == 'D'){
            if (nodeTPtr->trans.transHorse.disciplineCount == 0)
                numDel++;
            else
                numDisc++;
        }
        else if(nodeTPtr->trans.transCode == 'P'){
            numP++;
        }        
        nodeTPtr = nodeTPtr->nextLNT;
    }
}//end List::getNumTrans()

//********************************************************************
// FUNCTION NAME: TransactOnce()
// FUNCTION PURPOSE: Performs a single transaction.  
//            [skip] number of transactions at the beginning of the linked list of trans are skipped.
//            The transaction immediately after the skipped transactions is attempted.
//            If the transaction fails, skip is incremented and the function returns false.
//            In any case, thisTrans is returned by reference as the transaction that was just attempted.
// INPUT PARAMETERS:
//      1. int &skip        - the number of transactions to skip
//      2. TRANS &thisTrans    - the returned transaction that was just attempted
//      3. string &failString    - the ERROR, if any.
//RETURN VALUE – bool
//********************************************************************
bool TransactOnce(int &skip, TRANS &thisTrans, string &failString){
    bool success = true;
    stringstream failStream;

    ListNodeT *nodeTPtr;
    nodeTPtr = headTrans;
    HORSE dummyHorse;    //for ViewHorse()

    //if 'A', the ID must not already exist in our list of horses
    //if 'D' or 'P', the horse must already exist in our list of horses.
    //if 'D' and disciplineCount != 0, then
        //the existing horse must already have disciplineCount <4
        //transaction's transHorse.discipline[] must not have duplicates in the array
        //each of transaction's transHorse.discipline[]s must be valid (1<= discipline <=4)

    //find the transaction in question
    for (int i=0; i < skip; i++){
        nodeTPtr = nodeTPtr->nextLNT;
    }
    //nodeTPtr is now pointing to the appropriate ListNodeT.

    if (nodeTPtr->trans.transCode == 'A' && !List::InsertHorse(nodeTPtr->trans.transHorse)){
            failStream << "ERROR for horse transaction" << nodeTPtr->trans.transHorse.ID << " via InsertHorse().";
            success = false;
    }
    else if (nodeTPtr->trans.transCode == 'D'){    //delete or update disciplines
        if(nodeTPtr->trans.transHorse.disciplineCount == 0 && !List::DeleteHorse(nodeTPtr->trans.transHorse.ID)){    //for deletion
            failStream << "ERROR for horse transaction" << nodeTPtr->trans.transHorse.ID << " via DeleteHorse().";
            success = false;
        }
        else if(nodeTPtr->trans.transHorse.disciplineCount != 0 && !List::UpdateDisc(nodeTPtr->trans)){    //update disciplines
            failStream << "ERROR for horse transaction" << nodeTPtr->trans.transHorse.ID << " via UpdateDisc().";
            success = false;
        }
    }
    else if (nodeTPtr->trans.transCode == 'P' && !List::UpdatePrice(nodeTPtr->trans)){
        failStream << "ERROR for horse transaction" << nodeTPtr->trans.transHorse.ID << " via UpdatePrice().";
        success = false;
    }
    else {
        failStream << "ERROR for horse transaction" << nodeTPtr->trans.transHorse.ID << ", not a valid transCode.";
        success = false;
    }

    if (success){    //attempt to delete the transaction
        if (!List::DeleteTrans(nodeTPtr->trans.transHorse.ID)){
            failStream << "ERROR, could not delete transaction " << nodeTPtr->trans.transHorse.ID << ".";
            success = false;
        }
        else    //return true and error free
            failStream << "No error to report.";
    }
    if (!success)
        skip++;

    failStream << "\n";
    failString = failStream.str();
    return success;
}//end TransactOnce()

//********************************************************************
// FUNCTION NAME: UpdateDisc()
// FUNCTION PURPOSE: for an "update discipline" transaction, update the disciplines of that horse in inventory.
// INPUT PARAMETERS:
//      1. TRANS thisTrans    - the transaction to be executed
//RETURN VALUE – bool
//********************************************************************
bool List::UpdateDisc(TRANS thisTrans){
    bool success = true;
    ListNodeH *nodeHPtr = headHorse;        //no need for a ListNodeT
    //obtain a pointer to the horse in question
    while (nodeHPtr != NULL && nodeHPtr->horse.ID < thisTrans.transHorse.ID)
        nodeHPtr = nodeHPtr->nextLNH;
    if(nodeHPtr == NULL)            //failed to find the horse
        success = false;
    //horse found; nodeHPtr->horse.ID == thisTrans.transHorse.ID
    else if(thisTrans.transCode != 'D')    //this isn't even a "D" transaction...
        success = false;
    else if(thisTrans.transHorse.disciplineCount == 0)    //nothing to do, this is for deletion
        success = false;
    else if(nodeHPtr->horse.disciplineCount + thisTrans.transHorse.disciplineCount > 4)
        success = false;        //too many disciplines
    else {
        //update the disciplines
        while(thisTrans.transHorse.disciplineCount !=0){
        nodeHPtr->horse.discipline[nodeHPtr->horse.disciplineCount] = thisTrans.transHorse.discipline[thisTrans.transHorse.disciplineCount-1];
            nodeHPtr->horse.disciplineCount++;
            thisTrans.transHorse.disciplineCount--;
        }//disciplines are now updated but perhaps not sorted

        //bubble-sort the horse's array of disciplines.
        int i, j;
        bool swaped = true;
        int tempInt;
        for(i = 1; (i <= nodeHPtr->horse.disciplineCount)&&swaped; i++){
            swaped = false;
            for (j=0; j< nodeHPtr->horse.disciplineCount-1; j++){
                if(nodeHPtr->horse.discipline[j] > nodeHPtr->horse.discipline[j+1]){
                    tempInt = nodeHPtr->horse.discipline[j];
                    nodeHPtr->horse.discipline[j] = nodeHPtr->horse.discipline[j+1];
                    nodeHPtr->horse.discipline[j+1] = tempInt;
                    swaped = true;
                }    
            }    
        }
    }//end update and sort horse's disciplines

    return success;
}//end List::UpdateDisc()

//********************************************************************
// FUNCTION NAME: UpdatePrice()
// FUNCTION PURPOSE: for an "update lowBid" transaction, update the lowBid of that horse in inventory.
// INPUT PARAMETERS:
//      1. TRANS thisTrans    - the transaction to be executed
//RETURN VALUE – bool
//********************************************************************
bool List::UpdatePrice(TRANS thisTrans){
    bool success = true;
    ListNodeH *nodeHPtr;
    nodeHPtr = headHorse;
    //obtain a pointer to the horse in question
    while (nodeHPtr != NULL && nodeHPtr->horse.ID < thisTrans.transHorse.ID)
        nodeHPtr = nodeHPtr->nextLNH;
    if(nodeHPtr == NULL)            //failed to find the horse
        success = false;
    //else, horse found; nodeHPtr->horse.ID == thisTrans.transHorse.ID
    else if(thisTrans.transCode != 'P')    //this isn't even a "P" transaction...
        success = false;
    else {    //update lowBid
        nodeHPtr->horse.lowBid = thisTrans.transHorse.lowBid;
    }

    return success;
}//end List::UpdatePrice()

//********************************************************************
// FUNCTION NAME: ReportOneTransaction()
// FUNCTION PURPOSE: prints to Report.out a single transaction.  called by Transact().
// INPUT PARAMETERS:
//      1. fstream &strm        - the stream to print to.
//      2. TRANS oneTrans        - the transaction being reported.
//RETURN VALUE – void
//********************************************************************
void List::ReportOneTransaction(fstream &strm, TRANS oneTrans){
    //some "Ragged Arrays"
    string breedDescription[MAXBREEDS+1] = {"Dummy", "Pleasure Saddle Horse", "American Fox Trotter", "Virginia Highlander", "Arabian"};//21
    string disciplineDescription[MAXDISCIPLINES+1] = {"Dummy", "Dressage", "Jumper", "Hunter", "Western Pleasure"};//16
    if (oneTrans.transCode == 'A')
        strm << "Horse ADDED to inventory named '" ;
    else 
        strm << "Horse REMOVED from inventory named '" ;
    strm << oneTrans.transHorse.name << "'"<< endl;
    strm << "______________________________________________________________________\n";//70
    strm <<"ID  Height Age M/F LowBid     "<< oneTrans.transHorse.disciplineCount << " Discipline(s):  Breed\n";
    strm << left << setw(3)  <<oneTrans.transHorse.ID        <<" ";//ID
    strm << left << setw(5)  <<setprecision(2) <<oneTrans.transHorse.height        <<"  ";//height (double)
    strm << left << setw(3)  <<oneTrans.transHorse.age        <<" ";//age
    strm << left << setw(1)  <<oneTrans.transHorse.genderCode;    //genderCode (char)
    strm << "   "<<left<<'$';
    strm << right << fixed << setw(8) << setprecision(2) << oneTrans.transHorse.lowBid ;//lowBid (double)
    strm << left << "  " << setw(16) << disciplineDescription[oneTrans.transHorse.discipline[0]] ;
    strm << "  " << breedDescription[oneTrans.transHorse.breed] << endl;

    for (int j=1; j < oneTrans.transHorse.disciplineCount; j++){
        strm << "                              ";
        strm << disciplineDescription[oneTrans.transHorse.discipline[j]] << endl;
    }
    strm << endl << endl;
}//end ReportOneTransaction()

3 个答案:

答案 0 :(得分:7)

您忘记了List:: TransactOnce,因此它正在尝试将其解析为独立功能。我几天前就这样做了......

答案 1 :(得分:1)

TransactOnce函数应该在声明时实现,作为List的成员函数:

改变这个:

bool TransactOnce(int &skip, TRANS &thisTrans, string &failString){

到此:

bool List::TransactOnce(int &skip, TRANS &thisTrans, string &failString){

答案 2 :(得分:0)

OP在这里。我想到了。

定义TransactOnce()

bool TransactOnce(.....)

应该是

bool List::TransactOnce(....)