Help: Command Pattern - link list

Started by
2 comments, last by Gage64 16 years, 9 months ago
Trying to add Command Pattern to a link list with no success, if someone can point me in the right direction. Note: There is a working Command pattern after the link code. Error: 'LinkList::displayList' : the name of a function parameter cannot be qualified Error: 'LinkList::insertFirst' : illegal call of non-static member function All the changes that I made to the link list have " ///////$$$$###cmd change" at the end


// trying to add Command pattern to link list
// (link list works fine without command pattern)
#include "stdafx.h"


//linkList2.cpp
//demonstrates linked list
#include <iostream>
using namespace std;
class Link;
class LinkList;
/////////////////////////////////////////////////////$$$$###cmd change
class Command {// 1. Create a class that encapsulates an object
private:   
	LinkList*  object;            //    and a member function
   void (LinkList::*method)();   // a pointer to a member function (the attri-
public:  
		//    bute's name is "method")
   Command( LinkList* obj = 0, void (LinkList::*meth)() = 0 ) {
      object = obj;            // the argument's name is "meth"
      method = meth;
   }
   void execute() {
      (object->*method)();     // invoke the method on the object
}  };

///////////////////////////////////////////////////// //$$$$###cmd change
class Link
{
public:
int iData; //data item (key)
double dData; //data item
Link* pNext; //next link in list
Command cmd;                                    ///////$$$$###cmd change

//-------------------------------------------------------------
Link(int id, double dd) : //constructor
iData(id), dData(dd), pNext(NULL)
{ }
//-------------------------------------------------------------
void displayLink() //display ourself: {22, 2.99}
{
cout << "{" << iData << ", " << dData << "} ";
}
}; //end class Link
////////////////////////////////////////////////////////////////
class LinkList
{
private:
Link* pFirst; //ptr to first link on list
Command cmd;             ///////$$$$###cmd change
public:
//-------------------------------------------------------------
//constructor
LinkList(Command c) : pFirst(NULL), cmd(c)////////$$$$###cmd change
{ } //(no links on list yet)
//-------------------------------------------------------------
~LinkList() //destructor (deletes links)
{
Link* pCurrent = pFirst; //start at beginning of list
while(pCurrent != NULL) //until end of list,
{
Link* pOldCur = pCurrent; //save current link
pCurrent = pCurrent->pNext; //move to next link
delete pOldCur; //delete old current
}
}
//-------------------------------------------------------------
void insertFirst(int id, double dd)
{ //make new link
Link* pNewLink = new Link(id, dd);
pNewLink->pNext = pFirst; //it points to old first link
pFirst = pNewLink; //now first points to this
}

//-------------------------------------------------------------
Link* find(int key) //find link with given key
{ //(assumes non-empty list)
Link* pCurrent = pFirst; //start at ‘first’
while(pCurrent->iData != key) //while no match,
{
if(pCurrent->pNext == NULL) //if end of list,
return NULL; //didn’t find it
else //not end of list,
pCurrent = pCurrent->pNext; //go to next link
}
return pCurrent; //found it
}
//-------------------------------------------------------------
bool remove(int key) //remove link with given key
{ //(assumes non-empty list)
Link* pCurrent = pFirst; //search for link
Link* pPrevious = pFirst;
while(pCurrent->iData != key)
{
if(pCurrent->pNext == NULL)
return false; //didn’t find it
else
{
pPrevious = pCurrent; //go to next link
pCurrent = pCurrent->pNext;
}
} //found it
if(pCurrent == pFirst) //if first link,
pFirst = pFirst->pNext; //change first
else //otherwise,
pPrevious->pNext = pCurrent->pNext; //bypass it
delete pCurrent; //delete link
return true; //successful removal
}
//-------------------------------------------------------------
void displayList() //display the list
{
cout << "List (first-->last): ";
Link* pCurrent = pFirst; //start at beginning of list
while(pCurrent != NULL) //until end of list,
{
pCurrent->displayLink(); //print data
pCurrent = pCurrent->pNext; //move to next link
}
cout << endl;
cmd.execute();  ///////$$$$###cmd change  (this makes no sence to me)

}
//-------------------------------------------------------------
}; //end class LinkList
////////////////////////////////////////////////////////////////
int main()
{

LinkList test( Command());
//LinkList test2(Command(&LinkList::displayList));
LinkList test2(Command(&test,&LinkList::displayList));
//LinkList test2(Command(&LinkList::insertFirst(22,2.99)));

return 0;

//LinkList theList; //make list
//theList.insertFirst(22, 2.99); //insert 4 items
//theList.insertFirst(44, 4.99);
//theList.insertFirst(66, 6.99);
//theList.insertFirst(88, 8.99);
//theList.displayList(); //display list
//int findKey = 44; //find item
//Link* pFind = theList.find(findKey);
//if( pFind != NULL)
//cout << "Found link with key " << pFind->iData << endl;
//else
//cout << "Can’t find link" << endl;
//int remKey = 66; //remove item
//bool remOK = theList.remove(remKey);
//if( remOK )
//cout << "Removed link with key " << remKey << endl;
//else
//cout << "Can’t remove link" << endl;
//theList.displayList(); //display list

} //end main()






// working command pattern

#include <iostream>  
#include <string>  
using namespace std;
class WashingMachine;

class Command {// 1. Create a class that encapsulates an object
private:   
	WashingMachine*  object;            //    and a member function
   void (WashingMachine::*method)();   // a pointer to a member function (the attri-
public:  
		//    bute's name is "method")
   Command( WashingMachine* obj = 0, void (WashingMachine::*meth)() = 0 ) {
      object = obj;            // the argument's name is "meth"
      method = meth;
   }
   void execute() {
      (object->*method)();     // invoke the method on the object
}  };

class WashingMachine {
   string   name;
   Command  cmd;               // cmd is a "black box", it is a method invoca-
public:                        //    tion promoted to "full object status"
   WashingMachine( string n, Command c ) : cmd( c ) {
      name = n;
   }
   void DryCleaning() {               // "this" is the sender, cmd has the receiver
      cout << name << " Dry Cleaning" << endl;
      cmd.execute();           // ask the "black box" to callback the receiver
   }
   void Drying() {
      cout << name << " Drying" << endl;
      cmd.execute();           // 4. When the sender is ready to callback to
   }                           //    the receiver, it calls execute()
   void Washing() {
      cout << name << " Washing" << endl;
      cmd.execute();
   }
   void PretendWash() {
      cout << name << " PretendWash" << endl;
}  };

void main( void ) {
   // Fred will "execute" Barney which will result in a call to passOn()
   // Barney will "execute" Betty which will result in a call to gossip()
   // Betty will "execute" Wilma which will result in a call to listen()
   WashingMachine MachineA(  "Machine A",  Command() );
   // 2. Instantiate an object for each "callback"
   // 3. Pass each object to its future "sender"
   WashingMachine MachineB( "Machine B",  Command( &MachineA,  &WashingMachine::PretendWash ) );
   WashingMachine MachineC( "Machine C", Command( &MachineB,  &WashingMachine::DryCleaning) );
   WashingMachine MachineD( "Machine D",   Command( &MachineC, &WashingMachine::Washing ) );
   MachineD.Drying();
   //Machine2.Drying();
   
	return;
}

// Fred is talking
// Barney is passing on
// Betty is gossiping
// Wilma is listening






[Edited by - pascalosti on July 25, 2007 9:20:48 PM]
Advertisement
It looks like you're trying to create some kind of closure here:
LinkList test2(Command(&LinkList::insertFirst(22,2.99)));

C++ doesn't support this construct at all, unfortunately (not natively, at least; you might have some luck using Boost's Boost.Bind library), so what you've typed is not legal C++ (you have to omit the attempts to specify parameters to insertFirst).

Also, your Command class's only constructor takes both the pointer to the object to invoke the member function on, and the member function pointer itself, but in main() you only pass the member function... so that's another problem.

You'll really, really want to look into Boost's Bind and Function libraries to do this, otherwise you'll be reimplementing a lot of ugly machinery and boilerplate stuff.

And finally, the obligitory "why aren't you using std::list?" question goes here.
Its an assignment thats making my head hurt.

I simplified it allot

LinkList test( Command());
LinkList test2(Command(&test,&LinkList::displayList));


void displayList() //display the list
{
cout << "testing ";
}

It has problems when it calls displayList (&test is fine)!
'LinkList::displayList' : the name of a function parameter cannot be qualified


There are no parameters?
Try putting LinkedList's declaration before Command's declaration, that is:

class LinkedList { ... };class Command { ... };

This topic is closed to new replies.

Advertisement