The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.

Itss been a few weeks (C++)

clsCorwinclsCorwin Registered User regular
edited December 2008 in Help / Advice Forum
Ok, so I'm working with some code from our book given to us for a priority queue. I've changed around the insert function to accommodate my needs, and I'm generating one lone error on compile. However, the error is because the compiler is using the old definition of the function.

Old definition of PQueueInsert from PQ.h
virtual void PQueueInsert(const pqItemType& NewItem;

My revised definition from PQ.h
virtual void PQueueInsert(int track, int time);

The line of code generating the error from driver.cpp and the error
forwardPQ.PQueueInsert( track, T );

c:\visual studio 2005\projects\disk sweep\disk sweep\driver.cpp(211) : error C2660: 'pqClass::PQueueInsert' : function does not take 2 arguments

If I change the line of code to have only 1 parameter and thwe subsequent error:
forwardPQ.PQueueInsert( track );

c:\visual studio 2005\projects\disk sweep\disk sweep\driver.cpp(211) : error C2664: 'pqClass::PQueueInsert' : cannot convert parameter 1 from 'int' to 'const pqItemType &'
        Reason: cannot convert from 'int' to 'const pqItemType'
        No constructor could take the source type, or constructor overload resolution was ambiguous

So it seems to me its still hanging on to the old definition of the function. I have already tried Rebuilding it, with the same results.

Also, in Visual Studio 2005, how the hell do I get my file menu toolbar back? Dam thing disappeared, and I can't find any option for it anywhere. Its annoying not having save all and open buttons anymore.

clsCorwin on

Posts

  • SmasherSmasher Starting to get dizzy Registered User regular
    edited December 2008
    Small quibble, that's a declaration rather than a definition.

    Did you change the arguments of the function definition (in the .cpp file) to reflect your changes? The only thing I can think of off the top of my head that would cause this problem is if you overloaded the function but forgot to do that.

    Smasher on
  • clsCorwinclsCorwin Registered User regular
    edited December 2008
    Yes I did. I've triple chcecked that my functions match in both the .cpp and .h files.

    Thats why I'm so puzzled by this. It should work.

    clsCorwin on
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited December 2008
    Hmm, odd indeed. Did you overwrite/comment out the old function or did you overload it?

    Actually, if it's not horrendously long can you post the code (class declaration plus the PQueueInsert function definition(s)) here? If there's something subtle going on that'll probably help.

    Smasher on
  • SevorakSevorak Registered User regular
    edited December 2008
    Make sure you clean out anything left over from old compiles. In Visual Studio that's in Build->Clean Solution. It shouldn't make a difference, but the VS compiler can be pretty bad about knowing what need to be rebuilt.

    Other than that, if you made the changes to the method signature in a different file than the original, make sure you're #including the right version. But it looks like you're using the same file, so that won't matter.

    Sevorak on
    steam_sig.png 3DS: 0748-2282-4229
  • clsCorwinclsCorwin Registered User regular
    edited December 2008
    Yea, I did clean it, and then did a fresh build from the same menu.

    And yea, file name is the same, so the #include is the same

    clsCorwin on
  • clsCorwinclsCorwin Registered User regular
    edited December 2008
    driver.cpp
    #include <iostream> #include <sstream> #include <fstream> #include <string> #include "PQ.h" #include "Driver.h" using namespace std; void mainMenu() { trackPosition = 0; //set initial head position to track 0 int menuChoice; cout << "Please select an option:\n"; cout << "1. Enter commands manually\n"; cout << "2. Menu driven interface\n"; cout << "3. Run commands from a file\n"; menuChoice = getIntInput(); switch( menuChoice ) { case 1: manualInput(); break; case 2: commandMenu(); break; case 3: fileMenu(); break; default: cout << "Invalid option.\n\n"; mainMenu(); break; } } //functions for file input void fileMenu() { int menuChoice; string filename; cout << "Please select an option:\n"; cout << "1. Specify a command file\n"; cout << "2. Run using default command file (command.txt)\n"; menuChoice = getIntInput(); switch( menuChoice ) { case 1: filename = getStringInput(); getFileInput( filename ); break; case 2: getFileInput("command.txt"); break; default: cout << "Invalid option.\n\n"; fileMenu(); break; } } COMMAND toCmd(string cmd) //converts char to the SYMBOL equivalent { COMMAND result; if( cmd.compare("ServeReuest") == 0) //checks if the command is ServeRequest result = ServeRequest; else if( cmd.compare("PrintState") == 0) //checks if the command is PrintState result = PrintState; else if( cmd.compare("Quit") == 0) //checks if the command is Quit result = Quit; else { result = EnqRequest; //otherwise the command must be EnqRequest string temp = cmd.substr(11); //create a substr containing the integer parameter istringstream ss( temp ); ss >> parameter; //convert param within the string to an int } return result; } void getFileInput(string filename) { ifstream fin( filename.c_str() ); while( !fin.eof() ) //get data from file { getline(cin, command); //get line from file processFileInput( toCmd(command) ); //send command to be processed } fin.close(); //close file stream } void manualInput() { cout << "\nCommands are: EnqRequest <int>, ServeRequest, PrintState, and Quit\n@:>"; getline(cin, command); processFileInput(toCmd(command) ); manualInput(); } void processFileInput(COMMAND cmd) { switch( cmd ) //switching on cmd { case 0: //EnqRequest command cout << command << endl; //echo command enqueueRequest(parameter); break; case 1: //ServeRequest command cout << command << endl; //echo command serveRequest(); break; case 2: //PrintState command cout << command << endl; //echo command printState(); break; case 3: //Quit command cout << command << endl; //echo command quit(); break; } }//end of file I/O functions string getStringInput() { cout << "\n@:>"; string str; getline(cin, str); cout << "\n"; return str; } int getIntInput() { cout << "\n@:>"; string str; int data; getline(cin, str); istringstream ss( str ); //convert string to an int ss >> data; cout << "\n"; return data; } void commandMenu() { int menuChoice, track; cout << "Please enter the number of the action you wish to take.\n"; cout << "1. Enqueue Request\n"; cout << "2. Serve Request\n"; cout << "3. Print State\n"; cout << "4. Quit\n"; menuChoice = getIntInput(); switch( menuChoice ) //switching on menuChoice { case 1: //EnqRequest command cout << "Enter a track (0-9) to enqueue: "; track = getIntInput(); cout << endl << "EnqRequest " << track << endl << endl; //echo command enqueueRequest(track); commandMenu(); //return to menu break; case 2: //ServeRequest command cout << endl << "ServeRequest" << endl << endl; //echo command serveRequest(); commandMenu(); //return to menu break; case 3: //PrintState command cout << endl << "PrintState" << endl << endl; //echo command printState(); commandMenu(); //return to menu break; case 4: //Quit command cout << endl << "Quit" << endl << endl; //echo command quit(); break; } } //command functions void enqueueRequest(int track) { if( sweepingForward ) if( track > trackPosition ) { forwardPQ.PQueueInsert( track ); //new track has not passed, so it will be enqueued forward T++; } else { // reversePQ.PQueueInsert( track ); //otherwise it is put in reverse position T++; } if( sweepingReverse ) if( track < trackPosition ) { // reversePQ.PQueueInsert( track ); T++; } else { // forwardPQ.PQueueInsert( track ); T++; } } void serveRequest() { if( sweepingForward ) { //make sure you don't stay in same place } if( sweepingReverse ) { } if( trackPosition == 0 ) //track retuirned to 0 position, ready to sweep forward { sweepingForward = true; sweepingReverse = false; } if( trackPosition == 9 ) //track retuirned to 9 position, ready to sweep reverse { sweepingForward = false; sweepingReverse = true; } } void printState() { cout << "Current Position: .............. TRACK " << trackPosition << endl; if( sweepingForward ) { cout << "Current Direction: ............. FORWARD DIRECTION\n"; cout << "Current Queue: ................. FORWARD QUEUE\n\n"; } if( sweepingReverse ) { cout << "Current Direction: ............. REVERSE DIRECTION\n"; cout << "Current Queue: ................. REVERSE QUEUE\n\n"; } cout << "Contents of FORWARD QUEUE:\n" << "Track Request Number\n"; forwardPQ.PQueuePrint(); cout << "\nContents of REVERSE QUEUE:\n" << "Track Request Number\n"; reversePQ.PQueuePrint(); cout << "\n\n"; ofstream fout("output.txt", ofstream::app); } void quit() //does nothing to ensure next line of code to execute is return 0; in main() { cout << "\nQuit command received ... exiting."; } int main() { mainMenu(); return 0; }

    driver.h
    enum COMMAND { EnqRequest = 0, ServeRequest = 1, PrintState = 2, Quit =3 }; //for easy input later in switch statement string command; int parameter, trackPosition; bool sweepingForward = true; bool sweepingReverse = false; int T = 0; //timestamp //data members string getStringInput(); int getIntInput(); pqClass forwardPQ, reversePQ; //File I/O functions COMMAND toCmd(string cmd); void processFileInput(COMMAND cmd); void getFileInput(string filename); void manualInput(); //menu functions void mainMenu(); void commandMenu(); void fileMenu(); //disk scheduling functions void enqueueRequest(int track); void serveRequest(); void printState(); void quit();

    PQ.cpp
    // ********************************************************* // Implementation file PQ.cpp for the ADT priority queue. // A heap represents the priority queue. // ********************************************************* #include "PQ.h" // header file for priority queue bool pqClass::PQueueIsEmpty() const { return H.heapIsEmpty(); } // end PQueueIsEmpty void pqClass::PQueueInsert(int track, int time)//, bool& Success) { N.setTime(time); N.setTrack(track); H.heapInsert(N);//, Success); } // end PQueueInsert void pqClass::PQueueDelete(pqItemType& PriorityItem)//, bool& Success) { H.heapDelete(PriorityItem);//, Success); } // end PQueueDelete void pqClass::PQueuePrune(pqItemType& LastItem) { H.heapPrune(LastItem); } void pqClass::PQueuePrint() { H.printHeap(); } // End of implementation file.

    PQ.h
    // ********************************************************* // // Header file PQ.h for the ADT priority queue. // // Heap implementation. // // ********************************************************* // #include "Heap.h" // ADT heap operations #include "Node.h" typedef HeapItemType pqItemType; class pqClass { Heap H; Node N; public: // default constructor, copy constructor, and // destructor are supplied by the compiler // priority-queue operations: virtual bool PQueueIsEmpty() const; virtual void PQueueInsert(int track, int time);//, bool& Success); virtual void PQueueDelete(pqItemType& PriorityItem);//, bool& Success); virtual void PQueuePrune(pqItemType& LastItem); virtual void PQueuePrint(); }; // end class // End of header file.

    Heap.cpp
    /** @file Heap.cpp */ #include <iostream> #include "Heap.h" // header file for class Heap using namespace std; Heap::Heap() : size(0) { } // end default constructor Heap::~Heap() { } // end destructor bool Heap::heapIsEmpty() const { return bool(size == 0); } // end heapIsEmpty void Heap::heapInsert(const HeapItemType& newItem) throw(HeapException) // Method: Inserts the new item after the last item in the // heap and trickles it up to its proper position. The // heap is full when it contains MAX_HEAP items. { if (size >= MAX_HEAP) throw HeapException("HeapException: Heap full"); // place the new item at the end of the heap items[size] = newItem; // trickle new item up to its proper position int place = size; int parent = (place - 1)/2; while ( (parent >= 0) && (items[place].getTrack() > items[parent].getTrack()) ) { // swap items[place] and items[parent] HeapItemType temp = items[parent]; items[parent] = items[place]; items[place] = temp; place = parent; parent = (place - 1)/2; } // end while ++size; } // end heapInsert void Heap::printHeap() { for(int x = 0; x < size; x++) cout << items[x].getTrack() << " " << items[x].getTime() << endl; } void Heap::heapDelete(HeapItemType& rootItem) throw(HeapException) // Method: Swaps the last item in the heap with the root // and trickles it down to its proper position. { if (heapIsEmpty()) throw HeapException("HeapException: Heap empty"); else { rootItem = items[0]; items[0] = items[--size]; heapRebuild(0); } // end if } // end heapDelete void Heap::heapPrune(HeapItemType& lastItem) throw(HeapException) { if (heapIsEmpty()) throw HeapException("HeapException: Heap empty"); else { lastItem = items[size--]; //set lastItem to lowest number in heap then decriment size //no need for heapRebuild since we are pruning the tree from the bottom right, it will still be a heap and complete } } void Heap::heapRebuild(int root) { // if the root is not a leaf and the root's search key // is less than the larger of the search keys in the // root's children int child = 2 * root + 1; // index of root's left // child, if any if ( child < size ) { // root is not a leaf, so it has a left child at child int rightChild = child + 1; // index of right child, // if any // if root has a right child, find larger child if ( (rightChild < size) && (items[rightChild].getTrack() > items[child].getTrack()) ) child = rightChild; // index of larger child // if the root's value is smaller than the // value in the larger child, swap values if ( items[root].getTrack() < items[child].getTrack() ) { HeapItemType temp = items[root]; items[root] = items[child]; items[child] = temp; // transform the new subtree into a heap heapRebuild(child); } // end if } // end if // if root is a leaf, do nothing } // end heapRebuild // End of implementation file.

    Heap.h
    /** @file Heap.h */ const int MAX_HEAP = 20; //max 10 items for each queue representing the priorities #include "HeapException.h" #include "Node.h" //#include "KeyedItem.h" // definition of KeyedItem //typedef KeyedItem HeapItemType; typedef Node HeapItemType; class Heap { public: Heap(); virtual ~Heap(); virtual bool heapIsEmpty() const; virtual void heapInsert(const HeapItemType& newItem) throw(HeapException); virtual void printHeap(); /** Retrieves and deletes the item in the root of a heap. This * item has the largest search key in the heap. * @pre None. * @post If the heap was not empty, rootItem is the retrieved * item, the item is deleted from the heap. * @throw HeapException If the heap is empty. */ virtual void heapDelete(HeapItemType& rootItem) throw(HeapException); virtual void heapPrune(HeapItemType& lastItem) throw(HeapException); protected: /** Converts the semiheap rooted at index root into a heap. */ void heapRebuild(int root); private: HeapItemType items[MAX_HEAP]; /** Array of heap items. */ int size; /** Number of heap items. */ }; // end Heap // End of header file.


    Node.cpp
    #include "Node.h" int Node::getTrack() { return track; } int Node::getTime() { return timestamp; } void Node::setTrack(int track) { track = track; } void Node::setTime(int time) { timestamp = time; }

    Node.h
    class Node { int timestamp; int track; public: int getTime(); void setTime(int time); int getTrack(); void setTrack(int track); };

    Some info, this is to simulate a disk scheduling program, using priority queues to control the list of tracks to visit on the forward and reverse sweeps of the track arm.

    Originally, the heap used KeyedItem, which was just a wrapper for a data type with a function to retrieve that data. I changed it to a node with 2 data items, since I need to put both the track # and a timestamp for that # in there.

    clsCorwin on
  • bowenbowen Sup? Registered User regular
    edited December 2008
    Okay, the offending line is at 211 in your project in driver.cpp:
    forwardPQ.PQueueInsert( track );	//new track has not passed, so it will be enqueued forward
    

    Track is an int, which won't work with your method's definition on line 19 in PQ.h
    virtual void PQueueInsert(const pqItemType& NewItem);//, bool& Success);
    

    Which is typedef-ed as HeapItemType (which consequently becomes typedef-ed as a Node)

    If you fix track or change your signature on the method you should be okay. Which do you want it to be?

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • clsCorwinclsCorwin Registered User regular
    edited December 2008
    ... I think I realize what my problem is.

    I saved newer versions of the files in question to a different location, but at compile it was grabbing files from within the folder. I probably should have saw that coming. Lemme try a little file switcharoo...

    upon closer inspection, it was grabbing my driver from the alt location just fine, but neglecting PQ.h and PQ.cpp... very odd

    yep, that was it. Thanks.

    clsCorwin on
Sign In or Register to comment.