Jump to content
  • Advertisement
Sign in to follow this  
Toolmaker

RTTI system in C++

This topic is 5051 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently in the need of a (simple) RTTI system for my current project. At this point I use #defines and a DWORD value(Which is returned by TypeOf()). However, using this method is pretty much error prone(By small mistake one can define the same number twice), so I was looking for something better. Any ideas, that don't require STRANGE magic? Toolmaker

Share this post


Link to post
Share on other sites
Advertisement
The Loki library has a full TypeInfo class which makes it possible to compare type_info objects.

My usual question is, what are you using it for? It is quite possible (even likely) that using RTTI is the wrong solution to the problem.

Share this post


Link to post
Share on other sites
Fruny, what do you mean by that? Got any examples? Is that boost or something?

Petewood: I'm building a server. When storing all the clients, I make no difference between a client that's logging in, a client that's connected and NPCs. It's all just 1 big list.

However, when a user that's logging in is done, it returns a new object(A CUser object) which I push back into the list, and then delete the login session from the list. At this point, my update loop looks like this(Psuedo code)


for (iterate client list)
{
ret = client->Update();
if (ret < 0)
{
OnClientDisconnect(client);
}
else if (ret > 0)
{
if (client->TypeOf() == LoginSession)
OnClientLogin(client);
else
OnChatMessage(client);
}
}


The loop is going to be a bit bigger to support commands aswell, but basicly I need to be able to determine the type in some cases.

Toolmaker

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker

for (iterate client list)
{
ret = client->Update();
if (ret < 0)
{
OnClientDisconnect(client);
}
else if (ret > 0)
{
if (client->TypeOf() == LoginSession)
OnClientLogin(client);
else
OnChatMessage(client);
}
}


The loop is going to be a bit bigger to support commands aswell, but basicly I need to be able to determine the type in some cases.

Toolmaker

Why isn't all that logic inside the client iself?

class Client {
void update () {
// OnChatMessage stuff
}
};

class LoginSession: public Client {
void update () {
// OnClientLogin stuff
}
};

for (client in client_list) {
client.update();
}

Either the loop you posted is missing some important feature that's present in the real one, or you're doing things the wrong way.

That said:

if (dynamic_cast<LoginSession*>(client))
OnClientLogin(client);
else
OnChatMessage(client);


However, it looks like you need to destroy the client object once it logs in. That seems a bit silly, to me.

Rule of thumb: When you're switching on types, it will usually be better to dispatch to virtual functions instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
Fruny, what do you mean by that? Got any examples? Is that boost or something?


No, it's pure C++ RTTI. The C++ typeid operator returns a std::type_info object which contains, well, type information. You can compare two such objects to detect whether two objects are of the same (dynamic) type.

For your current problem, there are much better solutions: virtual functions


class AbstractClientSession
{
public:
virtual ~AbstractClientSession() {};
virtual int Update() = 0;
virtual void Disconnect() = 0;
virtual void Handle() = 0;
};

class LoginSession : public AbstractClientSession
{
int Update() {}
void Disconnect() { /* OnClientDisconnect(*this); */ }
void Handle() { /* OnClientLogin(*this); */ }
}
};

class ChatSession : public AbstractClientSession
{
int Update() {}
void Disconnect() { /* OnClientDisconnect(*this); */ }
void Handle() { /* OnChatMessage(*this); */ }
};

...
// client is of type AbstractClientSession*

for (iterate client list)
{
ret = client->Update();
if (ret < 0)
{
client->Disconnect()
}
else if (ret > 0)
{
client->Handle()
}
}


Quote:
The loop is going to be a bit bigger to support commands aswell, but basicly I need to be able to determine the type in some cases.


If you're just going to do the equivalent of a switch on the type, you don't need explicit RTTI. You use virtual functions through a common interface. Worst case, if you need to call member functions which are not part of the base class, you use a dynamic_cast, but that should never be your first choice.

Share this post


Link to post
Share on other sites
Well, I DO have a CClientBase class, from which I derive the LoginSession and User class. However, I implemented some events in both the server controller and the client class. The reason is simple:

OnClientLogin iterates the entire client list and calls the event for each client. OnClientDisconnect does the same and also cleans up the client that disconnected. This makes the main loop a little cleaner by moving all the work to functions.

The reason I have the server controller do this kind of work is because the controller is actually storing the clients, the listen socket, etc. But basicly, the events just reroute messages from the triggering client to the other clients.

Ofcourse, this brings in 1 other question: Should I move the loginsession handling code into the class itself AND give that class access to the user list, OR just keep it inside the server as it is now?

Toolmaker

Share this post


Link to post
Share on other sites
How about function overloading then?

void Server::Handle(Client *client);
void Server::Handle(LoginSession *login);



...
else if (ret > 0)
{
Handle(client);
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!