• 13
• 27
• 9
• 9
• 20

C++ Trick

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

Recommended Posts

Hey everyone, I'd just like to share a little trick I found with C++ that helped make the use of classes much nicer. [and partially for more experienced programmers to say that it's a terrible idea, heheh] The 'trick' is simply that class functions can be called from a null pointer. For example, say you have a class for a quake-style console. It has a simple interface of console::newtext(char *). Generally you'd like to use it to bump out error messages, game information, things like that. But how do you know if it's been setup already? You could make a singleton of it, but what about more complex things that might require multiple instances? You could assume a lot of things about game state, but what if something blows up the console, or if you can't make those assumptions? You could check that the global *gConsole exists each time you want to send info to it:
if (gConsole){
gConsole->newtext("Monkeys.");
}

But that just gets a little repetative, and what if you or other users forget to check? Using the little trick, you can do something like this:

void    console::newtext(char *intext){
//
//
//

if (!this){
return;
}
// otherwise proceed as normal
}

Now gConsole::newtext will always "succeed", even if the actual display hasn't been setup yet, or if something unexpected has destroyed it. All of those if (gConsole) checks get moved into a reusable piece of code.

Share on other sites
It is a terrible idea, because it'll just pretend that everything is alright. If it doesn't exist, for whatever reason, that's an error. At the least, an exception should be thrown, but unless it's something that can be caught and fixed during runtime, the program really should be allowed to bomb.

Share on other sites
This will NOT work with virtual functions. In this case the function's address must be looked up in a pointer stored inside the object. So if you have a null pointer to the object, when it looks up the function in the table, it will end up calling who knows what - it's very unlikely it will manage to get to the if (!this).

Share on other sites
But what if the object not existing is alright?

Say the game has 4-5 states, where the console exists in only 3 of them. Does every single area of code need to be aware of the game state? What if simply dumping the messages is the correct behavior?

Share on other sites
then you seriously need to rethink your design.

Share on other sites
I have learned that it is useful to automatically substitute the words "unmaintainable" for "clever" and "bug generator" for "trick" when talking about code. The phrase "clever trick" becomes "unmaintainable bug generator".

Share on other sites
Checking if it's null like that is silly. A better idea would be to assert the pointer. If the console is NULL at any point where you are trying to use it, chances are you've already skrewed up.

Share on other sites
*nod* thank you for the feedback.

Out of curiosity, what is the alternative?

Share on other sites
Well, null pointers usually signify a programming bug.

if(Console)  Console->Write("Hello World");

you would write
assert(Console != NULL); before any usage of Console...Console->Write("Hello World");

This way an assert will be triggered before you ever get to use the Console, and instead of silently passing by the null console pointer, it will shout out to you (in debug mode) "Hey, you messed up! You have a null pointer here! Fix it biznitch!"