Advertisement

Passing Class Pointers...

Started by July 11, 2000 03:22 AM
1 comment, last by gimp 24 years, 5 months ago
(Following is based on the "Pluggable Factories Rock My Multiplayer World"] Ok, this is driving me nuts. I designed my system with these as THE core component for handling my queue''s. I''m still trying to make ''pluggable factories'' actually work, and , I''m pretty sure I''m getting the class pointers wrong. If you havent read the tutorial here is a short of whats happening. Class B is derived from class A. Class B has a static member fucntion that causes it to be initialised at startup(whatever that means). Now, when class B''s static member is initialised the constructor is called. The constructor sends a pointer to itself through to class A where it is recorded in a map. Now the problem I have is that I''m not entirly sure of the syntax for passing this pointer. I also don''t understand if the initialised class that is started at app start is a full object?(as in the same as a ''newed'' one) The following code shows a meager attempt at understanding this subject:
    
class MessageRegistry
{
public:

	RegisterMessageID(unsigned char messageid,this)
	{
		Registry.insert(messageid,this);
	}

	RegisterString(string messagestring,this)
	{
		Registry.insert(messagestring,this);
	}

	this Switch(unsigned char messageid)
	{
		return Registry.find(messageid).second;
	}

protected:
   typedef MessageRegistry* MessageHandlerPtr; 
   typedef map<string,MessageHandlerPtr> RegistryMap;	
   static RegistryMap Registry;
};
    
In my specific example I''m planning on registering two different types of messages, so eventially there will be two maps, one for console messages, the other for normal MessageID(enum) messages. If anyone has any source code it would be of help... Many thanks gimp
Chris Brodie
Whoa, cowboy. this is NOT a type, so I don''t know what it''s doing in your parameter lists and return values. this is the pointer to the object being called, and its type is the object type (MessageRegistry in this case).

I think what you need to have as a type is the base class for your messages, like so:
    class MessageRegistry{public:  RegisterMessageID (unsigned char messageid, MessageHandlerPtr* sender)  {    Registry.insert(messageid, sender);  }  // etc., etc.};    


Also, very important, I think you''ve mis-defined MessageHandlerPtr as a MessageRegistry*. It should be a MessageHandler*, and you should have MessageHandler be some pure-virtual base class with the actual message-handling function to be overloaded by derived message-handler objects.

If I were using this class, I would make one object of the MessageRegistry class exist in the main class object--don''t make it a heap variable (i.e. don''t "new" it), because you only want one instance and you want it to go away when the program ends. Since the class doesn''t dynamically allocate memory, you don''t need a destructor to free anything. Actually, you could even derive your main class from MessageRegistry and have it do what you want.

I think what the author intended was for each of your message handler objects to have one instance of themselves somewhere, and for the constructor for each object to register itself with the MessageRegistry. For instance:
// WidgetHandler.hclass WidgetHandler : public MessageHandler{  WidgetHandler ()  {    mainClassPtr->RegisterMessageID (WIDGET_CODE, this);  }}; 


Now the real question comes as to where the object of WidgetHandler will be declared. This is tricky, because you must be certain that mainClassPtr has finished being constructed before any of the handlers are constructed. I''m not sure of the answer, but I could read the article & probably figure it out. Hope this has helped get you on the right path.



Advertisement
Ahhh... ok. I''ve had a bit of a rethink of my implementation. I''ve reread my manual on static member functions and class pointers and think I''m a bit closer. The ''this'' part should now be ok too (I think) as even derived objects hsould still have the same base type(I think thats how inheritence works)

Here is a new copy:

    typedef vector<unsigned char> ByteArray;enum MESSAGEID{	TEXT_MESSAGE,	MESSAGE_QUIT,	MESSAGE_MOVEMENT1};///////////////////////////////////////class BaseMessageIndex{public:protected:	void RegisterID(MESSAGEID messageid)	{		IDRegistry.insert((unsigned char)messageid,this);	}	void RegisterString(string &messagestring)	{		StringRegistry.insert(messagestring,this);	}	typedef map<unsigned char,	BaseMessageIndex*> IDRegistryMap;	typedef map<string,			BaseMessageIndex*> StringRegistryMap;	static IDRegistryMap		IDRegistry;	static StringRegistryMap	StringRegistry;};class MessageSwitch : public BaseMessageIndex{public:	void MessageData(ByteArray &Data)	{		if (Data[0] == TEXT_MESSAGE)		{			//Data is string based. Check string map.(case insensitive)		}		else		{			//Data is ID based. Check ID map.		}	}};class QuitMessageHandler : public BaseMessageIndex{public:	QuitMessageHandler()	{		RegisterID(MESSAGE_QUIT);		RegisterString(NULL + "QUIT");	}private :	static void dummy(void);};    


I''m still having problems with the inserts. Specifically with this error:

c:\program files\microsoft visual studio\vc98\myprojects\pluggablefactory\plug.h(26) : error C2664: ''class std::_Tree


std::char_traits,class std::allocator > >,class std::allocator >::iterator''
No constructor could take the source type, or constructor overload resolution was ambiguous

I hope your able to help, I feel so close now...

Once again, many thanks.

Chris ''gimp'' Brodie
Chris Brodie

This topic is closed to new replies.

Advertisement